Files
mailgoserver/internal/db/crud_ip_blacklist_test.go
T

100 lines
2.6 KiB
Go

package db
import (
"path/filepath"
"testing"
"time"
)
func openTestDB(t *testing.T) *DB {
t.Helper()
database, err := Open(filepath.Join(t.TempDir(), "test.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { database.Close() })
return database
}
// TestBlacklistIPEscalation confirms repeat offenses double the block duration up to the cap.
func TestBlacklistIPEscalation(t *testing.T) {
d := openTestDB(t)
const ip = "203.0.113.7"
wantHours := []int{12, 24, 48, 96, 168, 168} // caps at 168 (7 days)
for i, want := range wantHours {
if err := d.BlacklistIP(ip, "test", 12, 168); err != nil {
t.Fatalf("offense %d: %v", i+1, err)
}
list, err := d.ListBlacklist()
if err != nil {
t.Fatal(err)
}
if len(list) != 1 {
t.Fatalf("offense %d: expected 1 entry, got %d", i+1, len(list))
}
e := list[0]
if e.OffenseCount != i+1 {
t.Errorf("offense %d: OffenseCount = %d, want %d", i+1, e.OffenseCount, i+1)
}
gotHours := e.ExpiresAt.Sub(e.BlacklistedAt).Hours()
if diff := gotHours - float64(want); diff < -1 || diff > 1 {
t.Errorf("offense %d: duration = %.1fh, want ~%dh", i+1, gotHours, want)
}
}
}
// TestCountFailedAuthAttemptsByIPMatchesCurrentTimestamp guards against the exact
// SQLite time.Time/CURRENT_TIMESTAMP format mismatch already found once in
// CountRecentFailedAttempts: a row inserted via CURRENT_TIMESTAMP must be found by a
// since-cutoff comparison using a Go-side time.Time a moment earlier.
func TestCountFailedAuthAttemptsByIPMatchesCurrentTimestamp(t *testing.T) {
d := openTestDB(t)
const ip = "198.51.100.9"
since := time.Now().Add(-1 * time.Minute)
if err := d.LogAuthAttempt("sender", "someone@example.com", ip, false, "bad password"); err != nil {
t.Fatal(err)
}
n, err := d.CountFailedAuthAttemptsByIP(ip, since)
if err != nil {
t.Fatal(err)
}
if n != 1 {
t.Fatalf("CountFailedAuthAttemptsByIP = %d, want 1 (CURRENT_TIMESTAMP/time.Time format mismatch?)", n)
}
blacklisted, err := d.IsIPBlacklisted(ip)
if err != nil {
t.Fatal(err)
}
if blacklisted {
t.Fatal("IP should not be blacklisted yet")
}
}
func TestIPAbuseWhitelist(t *testing.T) {
d := openTestDB(t)
const ip = "192.0.2.55"
whitelisted, err := d.IsIPAbuseWhitelisted(ip)
if err != nil {
t.Fatal(err)
}
if whitelisted {
t.Fatal("should not be whitelisted before AddAbuseWhitelist")
}
if err := d.AddAbuseWhitelist(ip, "trusted scanner"); err != nil {
t.Fatal(err)
}
whitelisted, err = d.IsIPAbuseWhitelisted(ip)
if err != nil {
t.Fatal(err)
}
if !whitelisted {
t.Fatal("should be whitelisted after AddAbuseWhitelist")
}
}