mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-05-22 15:39:47 +02:00
56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
package audit
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// failureThrottle deduplicates high-frequency failure audit rows (e.g. wrong password).
|
|
type failureThrottle struct {
|
|
mu sync.Mutex
|
|
last map[string]time.Time
|
|
}
|
|
|
|
func newFailureThrottle() *failureThrottle {
|
|
return &failureThrottle{last: make(map[string]time.Time)}
|
|
}
|
|
|
|
// allow reports whether a row with the given key may be written now.
|
|
func (t *failureThrottle) allow(key string, cooldown time.Duration) bool {
|
|
if t == nil || cooldown <= 0 || key == "" {
|
|
return true
|
|
}
|
|
now := time.Now()
|
|
t.mu.Lock()
|
|
defer t.mu.Unlock()
|
|
if prev, ok := t.last[key]; ok && now.Sub(prev) < cooldown {
|
|
return false
|
|
}
|
|
t.last[key] = now
|
|
if len(t.last) > 4096 {
|
|
for k, ts := range t.last {
|
|
if now.Sub(ts) > cooldown*2 {
|
|
delete(t.last, k)
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// authFailureThrottleKey builds a per-IP key for auth failure deduplication.
|
|
func authFailureThrottleKey(category, action, clientIP string) string {
|
|
return category + ":" + action + ":" + clientIP
|
|
}
|
|
|
|
func isAuthFailureThrottled(category, action string) bool {
|
|
if category != "auth" {
|
|
return false
|
|
}
|
|
switch action {
|
|
case "login", "change_password":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|