diff options
| author | James Elliott <james-d-elliott@users.noreply.github.com> | 2025-02-24 18:49:15 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-24 18:49:15 +1100 |
| commit | 05fa254f27e6a1eee89abe8c5512d27de77cd7e7 (patch) | |
| tree | 8f56e80b855f611000fe142303026f0ed71ef7ed /internal/handlers/handler_authz_test.go | |
| parent | 194dd221ab7a5f2c9667b967532152df4914226a (diff) | |
feat(handlers): basic authz caching (#8320)
This adds the ability to cache successful basic authz attempts. This is done via a memory store that uses the HMAC-SHA256 algorithm to perform irreversible comparison of input parameters and has a maximum lifetime.
Closes #5006
Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
Diffstat (limited to 'internal/handlers/handler_authz_test.go')
| -rw-r--r-- | internal/handlers/handler_authz_test.go | 495 |
1 files changed, 480 insertions, 15 deletions
diff --git a/internal/handlers/handler_authz_test.go b/internal/handlers/handler_authz_test.go index e3161cb90..27400db87 100644 --- a/internal/handlers/handler_authz_test.go +++ b/internal/handlers/handler_authz_test.go @@ -84,11 +84,28 @@ func (s *AuthzSuite) Builder() (builder *AuthzBuilder) { func (s *AuthzSuite) BuilderWithBearerScheme() (builder *AuthzBuilder) { switch s.implementation { case AuthzImplExtAuthz: - return NewAuthzBuilder().WithImplementationExtAuthz().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + return NewAuthzBuilder().WithImplementationExtAuthz().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(time.Duration(0), model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) case AuthzImplForwardAuth: - return NewAuthzBuilder().WithImplementationForwardAuth().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + return NewAuthzBuilder().WithImplementationForwardAuth().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(time.Duration(0), model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) case AuthzImplAuthRequest: - return NewAuthzBuilder().WithImplementationAuthRequest().WithStrategies(NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + return NewAuthzBuilder().WithImplementationAuthRequest().WithStrategies(NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Duration(0), model.AuthorizationSchemeBasic.String(), model.AuthorizationSchemeBearer.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + case AuthzImplLegacy: + return NewAuthzBuilder().WithImplementationLegacy().WithStrategies(NewHeaderLegacyAuthnStrategy(), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + default: + s.T().FailNow() + } + + return nil +} + +func (s *AuthzSuite) BuilderWithProxyAuthorizationBasicSchemeCached() (builder *AuthzBuilder) { + switch s.implementation { + case AuthzImplExtAuthz: + return NewAuthzBuilder().WithImplementationExtAuthz().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(time.Minute, model.AuthorizationSchemeBasic.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + case AuthzImplForwardAuth: + return NewAuthzBuilder().WithImplementationForwardAuth().WithStrategies(NewHeaderProxyAuthorizationAuthnStrategy(time.Minute, model.AuthorizationSchemeBasic.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) + case AuthzImplAuthRequest: + return NewAuthzBuilder().WithImplementationAuthRequest().WithStrategies(NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Minute, model.AuthorizationSchemeBasic.String()), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) case AuthzImplLegacy: return NewAuthzBuilder().WithImplementationLegacy().WithStrategies(NewHeaderLegacyAuthnStrategy(), NewCookieSessionAuthnStrategy(schema.NewRefreshIntervalDurationAlways())) default: @@ -378,6 +395,348 @@ func (s *AuthzSuite) TestShouldVerifyFailureToGetDetailsUsingBasicScheme() { } } +func (s *AuthzSuite) TestShouldVerifyFailureToGetDetailsUsingBasicSchemeCached() { + if s.setRequest == nil { + s.T().Skip() + } + + authz := s.BuilderWithProxyAuthorizationBasicSchemeCached().Build() + + mock := mocks.NewMockAutheliaCtx(s.T()) + + defer mock.Close() + + setUpMockClock(mock) + + s.ConfigureMockSessionProviderWithAutomaticAutheliaURLs(mock) + + targetURI := s.RequireParseRequestURI("https://one-factor.example.com") + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + attempt := model.AuthenticationAttempt{ + Time: mock.Ctx.Clock.Now(), + Successful: true, + Banned: false, + Username: "john", + Type: regulation.AuthType1FA, + RemoteIP: model.NewNullIP(mock.Ctx.RemoteIP()), + RequestURI: "https://one-factor.example.com", + RequestMethod: fasthttp.MethodGet, + } + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(nil, fmt.Errorf("generic failure")), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(nil, fmt.Errorf("generic failure")), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } + + mock.Ctx.Request.Reset() + mock.Ctx.Response.Reset() + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(nil, fmt.Errorf("generic failure")), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(nil, fmt.Errorf("generic failure")), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } +} + +func (s *AuthzSuite) TestShouldVerifyFailureToCheckPasswordUsingBasicSchemeCached() { + if s.setRequest == nil { + s.T().Skip() + } + + authz := s.BuilderWithProxyAuthorizationBasicSchemeCached().Build() + + mock := mocks.NewMockAutheliaCtx(s.T()) + + defer mock.Close() + + setUpMockClock(mock) + + s.ConfigureMockSessionProviderWithAutomaticAutheliaURLs(mock) + + targetURI := s.RequireParseRequestURI("https://one-factor.example.com") + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + attempt := model.AuthenticationAttempt{ + Time: mock.Ctx.Clock.Now(), + Successful: false, + Banned: false, + Username: "john", + Type: regulation.AuthType1FA, + RemoteIP: model.NewNullIP(mock.Ctx.RemoteIP()), + RequestURI: "https://one-factor.example.com", + RequestMethod: fasthttp.MethodGet, + } + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, nil), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, nil), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } + + mock.Ctx.Request.Reset() + mock.Ctx.Response.Reset() + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, nil), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, nil), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } +} + +func (s *AuthzSuite) TestShouldVerifyErrorToCheckPasswordUsingBasicSchemeCached() { + if s.setRequest == nil { + s.T().Skip() + } + + authz := s.BuilderWithProxyAuthorizationBasicSchemeCached().Build() + + mock := mocks.NewMockAutheliaCtx(s.T()) + + defer mock.Close() + + setUpMockClock(mock) + + s.ConfigureMockSessionProviderWithAutomaticAutheliaURLs(mock) + + targetURI := s.RequireParseRequestURI("https://one-factor.example.com") + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + attempt := model.AuthenticationAttempt{ + Time: mock.Ctx.Clock.Now(), + Successful: false, + Banned: false, + Username: "john", + Type: regulation.AuthType1FA, + RemoteIP: model.NewNullIP(mock.Ctx.RemoteIP()), + RequestURI: "https://one-factor.example.com", + RequestMethod: fasthttp.MethodGet, + } + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, fmt.Errorf("bad data")), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, fmt.Errorf("bad data")), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } + + mock.Ctx.Request.Reset() + mock.Ctx.Response.Reset() + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, fmt.Errorf("bad data")), + ) + } else { + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(false, fmt.Errorf("bad data")), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + ) + } + + authz.Handler(mock.Ctx) + + switch s.implementation { + case AuthzImplAuthRequest, AuthzImplLegacy: + s.Equal(fasthttp.StatusUnauthorized, mock.Ctx.Response.StatusCode()) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate))) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + default: + s.Equal(fasthttp.StatusProxyAuthRequired, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal(`Basic realm="Authorization Required"`, string(mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate))) + } +} + func (s *AuthzSuite) TestShouldVerifyBypassWithErrorToGetDetailsUsingBasicScheme() { if s.setRequest == nil { s.T().Skip() @@ -654,6 +1013,114 @@ func (s *AuthzSuite) TestShouldApplyPolicyOfOneFactorDomain() { s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) } +func (s *AuthzSuite) TestShouldApplyPolicyOfOneFactorDomainCached() { + if s.setRequest == nil { + s.T().Skip() + } + + authz := s.BuilderWithProxyAuthorizationBasicSchemeCached().Build() + + mock := mocks.NewMockAutheliaCtx(s.T()) + + defer mock.Close() + + setUpMockClock(mock) + + s.ConfigureMockSessionProviderWithAutomaticAutheliaURLs(mock) + + targetURI := s.RequireParseRequestURI("https://one-factor.example.com") + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + if s.implementation == AuthzImplLegacy { + gomock.InOrder( + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(&authentication.UserDetails{ + Emails: []string{"john@example.com"}, + Groups: []string{"dev", "admins"}, + }, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(&authentication.UserDetails{ + Emails: []string{"john@example.com"}, + Groups: []string{"dev", "admins"}, + }, nil), + ) + } else { + attempt := model.AuthenticationAttempt{ + Time: mock.Ctx.Clock.Now(), + Successful: true, + Banned: false, + Username: "john", + Type: regulation.AuthType1FA, + RemoteIP: model.NewNullIP(mock.Ctx.RemoteIP()), + RequestURI: "https://one-factor.example.com", + RequestMethod: fasthttp.MethodGet, + } + + gomock.InOrder( + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + CheckUserPassword(gomock.Eq("john"), gomock.Eq("password")). + Return(true, nil), + mock.StorageMock. + EXPECT(). + AppendAuthenticationLog(gomock.Eq(mock.Ctx), gomock.Eq(attempt)).Return(nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(&authentication.UserDetails{ + Emails: []string{"john@example.com"}, + Groups: []string{"dev", "admins"}, + }, nil), + mock.StorageMock. + EXPECT(). + LoadBannedIP(gomock.Eq(mock.Ctx), gomock.Eq(model.NewIP(mock.Ctx.RemoteIP()))).Return(nil, nil), + mock.StorageMock. + EXPECT(). + LoadBannedUser(gomock.Eq(mock.Ctx), gomock.Eq("john")).Return(nil, nil), + mock.UserProviderMock.EXPECT(). + GetDetails(gomock.Eq("john")). + Return(&authentication.UserDetails{ + Emails: []string{"john@example.com"}, + Groups: []string{"dev", "admins"}, + }, nil), + ) + } + + authz.Handler(mock.Ctx) + + s.Equal(fasthttp.StatusOK, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) + + mock.Ctx.Request.Reset() + mock.Ctx.Response.Reset() + + s.setRequest(mock.Ctx, fasthttp.MethodGet, targetURI, true, false) + + mock.Ctx.Request.Header.Set(fasthttp.HeaderProxyAuthorization, "Basic am9objpwYXNzd29yZA==") + + authz.Handler(mock.Ctx) + + s.Equal(fasthttp.StatusOK, mock.Ctx.Response.StatusCode()) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderWWWAuthenticate)) + s.Equal([]byte(nil), mock.Ctx.Response.Header.Peek(fasthttp.HeaderProxyAuthenticate)) +} + func (s *AuthzSuite) TestShouldHandleAnyCaseSchemeParameter() { if s.setRequest == nil { s.T().Skip() @@ -676,9 +1143,7 @@ func (s *AuthzSuite) TestShouldHandleAnyCaseSchemeParameter() { defer mock.Close() - mock.Ctx.Clock = &mock.Clock - - mock.Clock.Set(time.Now()) + setUpMockClock(mock) s.ConfigureMockSessionProviderWithAutomaticAutheliaURLs(mock) @@ -885,8 +1350,8 @@ func (s *AuthzSuite) TestShouldApplyPolicyOfOneFactorDomainWithAuthorizationHead builder := NewAuthzBuilder().WithImplementationLegacy() builder = builder.WithStrategies( - NewHeaderAuthorizationAuthnStrategy("basic"), - NewHeaderProxyAuthorizationAuthRequestAuthnStrategy("basic"), + NewHeaderAuthorizationAuthnStrategy(time.Duration(0), "basic"), + NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Duration(0), "basic"), NewCookieSessionAuthnStrategy(builder.config.RefreshInterval), ) @@ -967,8 +1432,8 @@ func (s *AuthzSuite) TestShouldHandleAuthzWithoutHeaderNoCookie() { builder := NewAuthzBuilder().WithImplementationLegacy() builder = builder.WithStrategies( - NewHeaderAuthorizationAuthnStrategy("basic"), - NewHeaderProxyAuthorizationAuthRequestAuthnStrategy("basic"), + NewHeaderAuthorizationAuthnStrategy(time.Duration(0), "basic"), + NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Duration(0), "basic"), ) authz := builder.Build() @@ -1000,8 +1465,8 @@ func (s *AuthzSuite) TestShouldHandleAuthzWithEmptyAuthorizationHeader() { builder := NewAuthzBuilder().WithImplementationLegacy() builder = builder.WithStrategies( - NewHeaderAuthorizationAuthnStrategy("basic"), - NewHeaderProxyAuthorizationAuthRequestAuthnStrategy("basic"), + NewHeaderAuthorizationAuthnStrategy(time.Duration(0), "basic"), + NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Duration(0), "basic"), ) authz := builder.Build() @@ -1033,8 +1498,8 @@ func (s *AuthzSuite) TestShouldHandleAuthzWithAuthorizationHeaderInvalidPassword builder := NewAuthzBuilder().WithImplementationLegacy() builder = builder.WithStrategies( - NewHeaderAuthorizationAuthnStrategy("basic"), - NewHeaderProxyAuthorizationAuthRequestAuthnStrategy("basic"), + NewHeaderAuthorizationAuthnStrategy(time.Duration(0), "basic"), + NewHeaderProxyAuthorizationAuthRequestAuthnStrategy(time.Duration(0), "basic"), ) authz := builder.Build() @@ -1105,7 +1570,7 @@ func (s *AuthzSuite) TestShouldHandleAuthzWithIncorrectAuthHeader() { // TestSho builder := s.Builder() builder = builder.WithStrategies( - NewHeaderAuthorizationAuthnStrategy("basic"), + NewHeaderAuthorizationAuthnStrategy(time.Duration(0), "basic"), ) authz := builder.Build() |
