apiary/honeypot/store/cache.go
2021-09-17 02:01:43 +02:00

86 lines
2.2 KiB
Go

package store
import "github.uio.no/torjus/apiary/models"
type CachingStore struct {
backend LoginAttemptStore
totalStatsCache []StatsResult
usernameQueryCache map[string][]models.LoginAttempt
passwordQueryCache map[string][]models.LoginAttempt
ipQueryCache map[string][]models.LoginAttempt
}
func NewCachingStore(backend LoginAttemptStore) *CachingStore {
return &CachingStore{
backend: backend,
usernameQueryCache: make(map[string][]models.LoginAttempt),
passwordQueryCache: make(map[string][]models.LoginAttempt),
ipQueryCache: make(map[string][]models.LoginAttempt),
}
}
func (s *CachingStore) AddAttempt(l *models.LoginAttempt) error {
s.totalStatsCache = nil
delete(s.ipQueryCache, l.RemoteIP.String())
delete(s.passwordQueryCache, l.Password)
delete(s.usernameQueryCache, l.Username)
return s.backend.AddAttempt(l)
}
func (s *CachingStore) All() ([]models.LoginAttempt, error) {
return s.backend.All()
}
func (s *CachingStore) Stats(statType LoginStats, limit int) ([]StatsResult, error) {
// Only cache totals for now, as they are the most queried
if statType == LoginStatsTotals {
if s.totalStatsCache != nil {
return s.totalStatsCache, nil
}
stats, err := s.backend.Stats(statType, limit)
if err != nil {
return stats, err
}
s.totalStatsCache = stats
return stats, err
}
// TODO: Maybe cache the default limits
return s.backend.Stats(statType, limit)
}
func (s *CachingStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
switch query.QueryType {
case AttemptQueryTypeIP:
if attempts, ok := s.ipQueryCache[query.Query]; ok {
return attempts, nil
}
case AttemptQueryTypePassword:
if attempts, ok := s.passwordQueryCache[query.Query]; ok {
return attempts, nil
}
case AttemptQueryTypeUsername:
if attempts, ok := s.usernameQueryCache[query.Query]; ok {
return attempts, nil
}
}
attempts, err := s.backend.Query(query)
if err != nil {
return attempts, err
}
switch query.QueryType {
case AttemptQueryTypeIP:
s.ipQueryCache[query.Query] = attempts
case AttemptQueryTypeUsername:
s.ipQueryCache[query.Query] = attempts
case AttemptQueryTypePassword:
s.ipQueryCache[query.Query] = attempts
}
return attempts, err
}