Smail/backend/controllers/security_limiter_test.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

46 lines
1.5 KiB
Go

package controllers
import (
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestPublicSecurityLimitersIsolateIPAndExpire(t *testing.T) {
limiter := newLoginLimiter(2)
now := time.Date(2026, 8, 26, 12, 0, 0, 0, time.UTC)
limiter.now = func() time.Time { return now }
first := httptest.NewRequest(http.MethodPost, "https://mail.example.com/api/security", nil)
first.RemoteAddr = "192.0.2.10:1234"
second := httptest.NewRequest(http.MethodPost, "https://mail.example.com/api/security", nil)
second.RemoteAddr = "192.0.2.11:1234"
firstKey := limiter.ipKey(first)
secondKey := limiter.ipKey(second)
limiter.recordFailure(firstKey)
if limiter.blocked(firstKey) {
t.Fatal("public security limiter blocked the first attempt too early")
}
limiter.recordFailure(firstKey)
if !limiter.blocked(firstKey) {
t.Fatal("public security limiter did not block the repeated IP")
}
if limiter.blocked(secondKey) {
t.Fatal("public security limiter shared state across IPs")
}
now = now.Add(loginBlockTime + time.Second)
if limiter.blocked(firstKey) {
t.Fatal("public security limiter block did not expire")
}
}
func TestPublicSecurityLimiterUsesBoundedEntryStore(t *testing.T) {
limiter := newLoginLimiter(1)
for index := 0; index < loginMaxEntries+128; index++ {
limiter.recordFailure("public-ip-key-" + string(rune(index)))
}
if len(limiter.attempts) > loginMaxEntries {
t.Fatalf("public security limiter entries = %d, want <= %d", len(limiter.attempts), loginMaxEntries)
}
}