package httpsecurity import ( "errors" "net/http" "net/http/httptest" "testing" "proxy-pool/internal/config" ) func TestNewFromListenerMapsResolvedConfiguration(t *testing.T) { t.Parallel() listener := config.Listener{ Access: config.Access{ AllowCIDRs: []string{"198.51.100.0/24"}, TrustedProxies: []string{"10.0.0.0/8"}, }, Auth: config.Auth{Mode: ModeAny, Methods: []config.AuthMethod{ {Mode: ModeBearer, Value: "bearer-secret"}, {Mode: ModeAPIKey, Header: "X-API-Key", Value: "api-secret"}, }}, } protection, err := NewFromListener(listener, ClientAuthenticated, APIAuthSemantics, nil) if err != nil { t.Fatalf("NewFromListener() error = %v", err) } request := newRequest() request.Header.Set("Authorization", "Bearer bearer-secret") identity, err := protection.Resolve(request) if err != nil { t.Fatalf("Resolve() error = %v", err) } if identity.ClientID != credentialSubject("bearer", "bearer-secret") { t.Fatalf("identity = %+v", identity) } if _, err := protection.Resolve(httptest.NewRequest(http.MethodGet, "/", nil)); err == nil { t.Fatal("Resolve(request without remote address) error = nil") } } func TestBuildFromListenerAppliesConfiguredAdmissionLimits(t *testing.T) { t.Parallel() listener := config.Listener{ Auth: config.Auth{Mode: ModeNone}, Limits: config.Limits{RequestsPerMinute: 1, RequestsPerMinutePerClient: 1}, } protection, err := BuildFromListener(listener, ClientSourceIP, APIAuthSemantics) if err != nil { t.Fatalf("BuildFromListener() error = %v", err) } if _, err := protection.Resolve(newRequest()); err != nil { t.Fatalf("Resolve(first) error = %v", err) } _, err = protection.Resolve(newRequest()) var httpError *HTTPError if !errors.As(err, &httpError) || httpError.StatusCode != http.StatusTooManyRequests { t.Fatalf("Resolve(second) error = %T %v", err, err) } }