Skip to content

Commit c7dfb25

Browse files
Add IP-based rate limiting for password attempts
Co-authored-by: erikdubbelboer <522870+erikdubbelboer@users.noreply.github.com>
1 parent d075fca commit c7dfb25

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

internal/util/config_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package util
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestPasswordRateLimiter_Configuration(t *testing.T) {
10+
// Test that different configurations work
11+
tests := []struct {
12+
name string
13+
maxAttempts int
14+
windowSize time.Duration
15+
attempts int
16+
shouldBlock bool
17+
}{
18+
{
19+
name: "strict limit - 2 attempts per minute",
20+
maxAttempts: 2,
21+
windowSize: time.Minute,
22+
attempts: 2,
23+
shouldBlock: true,
24+
},
25+
{
26+
name: "lenient limit - 10 attempts per minute",
27+
maxAttempts: 10,
28+
windowSize: time.Minute,
29+
attempts: 5,
30+
shouldBlock: false,
31+
},
32+
{
33+
name: "very strict - 1 attempt per minute",
34+
maxAttempts: 1,
35+
windowSize: time.Minute,
36+
attempts: 1,
37+
shouldBlock: true,
38+
},
39+
}
40+
41+
for _, tt := range tests {
42+
t.Run(tt.name, func(t *testing.T) {
43+
rl := NewPasswordRateLimiter(tt.maxAttempts, tt.windowSize)
44+
defer rl.Close()
45+
46+
ctx := context.Background()
47+
ip := "192.168.1.100"
48+
49+
// Record the specified number of attempts
50+
for i := 0; i < tt.attempts; i++ {
51+
rl.RecordFailedAttempt(ctx, ip)
52+
}
53+
54+
// Check if next attempt should be blocked
55+
allowed := rl.IsAllowed(ctx, ip)
56+
blocked := !allowed
57+
58+
if blocked != tt.shouldBlock {
59+
t.Errorf("Expected blocked=%v but got blocked=%v", tt.shouldBlock, blocked)
60+
}
61+
})
62+
}
63+
}

0 commit comments

Comments
 (0)