feat: add GeoIP country lookup with embedded DB-IP Lite database (PLAN.md 4.3)
Embeds a DB-IP Lite country MMDB (~5MB) in the binary via go:embed, keeping the single-binary deployment story clean. Country codes are stored alongside login attempts and sessions, shown in the dashboard (Top IPs, Top Countries card, Recent/Active Sessions, session detail). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,17 +23,17 @@ func TestRecordLoginAttempt(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
// First attempt creates a new record.
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.1"); err != nil {
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.1", ""); err != nil {
|
||||
t.Fatalf("first attempt: %v", err)
|
||||
}
|
||||
|
||||
// Second attempt with same credentials increments count.
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.1"); err != nil {
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.1", ""); err != nil {
|
||||
t.Fatalf("second attempt: %v", err)
|
||||
}
|
||||
|
||||
// Different IP is a separate record.
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.2"); err != nil {
|
||||
if err := store.RecordLoginAttempt(ctx, "root", "toor", "10.0.0.2", ""); err != nil {
|
||||
t.Fatalf("different IP: %v", err)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestCreateAndEndSession(t *testing.T) {
|
||||
store := newTestStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "")
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("creating session: %v", err)
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func TestUpdateHumanScore(t *testing.T) {
|
||||
store := newTestStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "")
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("creating session: %v", err)
|
||||
}
|
||||
@@ -123,7 +123,7 @@ func TestAppendSessionLog(t *testing.T) {
|
||||
store := newTestStore(t)
|
||||
ctx := context.Background()
|
||||
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "")
|
||||
id, err := store.CreateSession(ctx, "10.0.0.1", "root", "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("creating session: %v", err)
|
||||
}
|
||||
@@ -159,7 +159,7 @@ func TestDeleteRecordsBefore(t *testing.T) {
|
||||
}
|
||||
|
||||
// Insert a recent login attempt.
|
||||
if err := store.RecordLoginAttempt(ctx, "new", "new", "2.2.2.2"); err != nil {
|
||||
if err := store.RecordLoginAttempt(ctx, "new", "new", "2.2.2.2", ""); err != nil {
|
||||
t.Fatalf("insert recent attempt: %v", err)
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ func TestDeleteRecordsBefore(t *testing.T) {
|
||||
}
|
||||
|
||||
// Insert a recent session.
|
||||
if _, err := store.CreateSession(ctx, "2.2.2.2", "new", ""); err != nil {
|
||||
if _, err := store.CreateSession(ctx, "2.2.2.2", "new", "", ""); err != nil {
|
||||
t.Fatalf("insert recent session: %v", err)
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ func TestNewSQLiteStoreCreatesFile(t *testing.T) {
|
||||
|
||||
// Verify we can use the store.
|
||||
ctx := context.Background()
|
||||
if err := store.RecordLoginAttempt(ctx, "test", "test", "127.0.0.1"); err != nil {
|
||||
if err := store.RecordLoginAttempt(ctx, "test", "test", "127.0.0.1", ""); err != nil {
|
||||
t.Fatalf("recording attempt: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user