Initial DDC release

This commit is contained in:
SirBlob committed 2026-10-25 20:24:50 -04:00
commit 434f6441da
57 files changed
+4606

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
package auth
import (
"sync"
"time"
)
const maxTrackedClients = 10000
type attemptWindow struct {
failures int
startedAt time.Time
}
type LoginLimiter struct {
mutex sync.Mutex
maxFailures int
window time.Duration
attempts map[string]*attemptWindow
}
func NewLoginLimiter(maxFailures int, window time.Duration) *LoginLimiter {
return &LoginLimiter{
maxFailures: maxFailures,
window: window,
attempts: make(map[string]*attemptWindow),
}
}
func (limiter *LoginLimiter) Allowed(client string) bool {
limiter.mutex.Lock()
defer limiter.mutex.Unlock()
attempt := limiter.current(client)
return attempt == nil || attempt.failures < limiter.maxFailures
}
func (limiter *LoginLimiter) RecordFailure(client string) {
limiter.mutex.Lock()
defer limiter.mutex.Unlock()
attempt := limiter.current(client)
if attempt == nil {
if len(limiter.attempts) >= maxTrackedClients {
limiter.removeExpired()
}
attempt = &attemptWindow{startedAt: time.Now()}
limiter.attempts[client] = attempt
}
attempt.failures++
}
func (limiter *LoginLimiter) Reset(client string) {
limiter.mutex.Lock()
defer limiter.mutex.Unlock()
delete(limiter.attempts, client)
}
func (limiter *LoginLimiter) current(client string) *attemptWindow {
attempt, found := limiter.attempts[client]
if !found {
return nil
}
if time.Since(attempt.startedAt) > limiter.window {
delete(limiter.attempts, client)
return nil
}
return attempt
}
func (limiter *LoginLimiter) removeExpired() {
for client, attempt := range limiter.attempts {
if time.Since(attempt.startedAt) > limiter.window {
delete(limiter.attempts, client)
}
}
}