diff --git a/cmd/authelia/main.go b/cmd/authelia/main.go index 8095c74d..d51b5e99 100644 --- a/cmd/authelia/main.go +++ b/cmd/authelia/main.go @@ -121,7 +121,7 @@ func startServer() { } clock := utils.RealClock{} - authorizer := authorization.NewAuthorizer(config.AccessControl) + authorizer := authorization.NewAuthorizer(config) sessionProvider := session.NewProvider(config.Session, autheliaCertPool) regulator := regulation.NewRegulator(config.Regulation, storageProvider, clock) oidcProvider, err := oidc.NewOpenIDConnectProvider(config.IdentityProviders.OIDC) diff --git a/internal/authorization/authorizer.go b/internal/authorization/authorizer.go index 4b553732..2cc79b5c 100644 --- a/internal/authorization/authorizer.go +++ b/internal/authorization/authorizer.go @@ -1,8 +1,6 @@ package authorization import ( - "github.com/sirupsen/logrus" - "github.com/authelia/authelia/internal/configuration/schema" "github.com/authelia/authelia/internal/logging" ) @@ -11,25 +9,20 @@ import ( type Authorizer struct { defaultPolicy Level rules []*AccessControlRule + configuration *schema.Configuration } // NewAuthorizer create an instance of authorizer with a given access control configuration. -func NewAuthorizer(configuration schema.AccessControlConfiguration) *Authorizer { - if logging.Logger().IsLevelEnabled(logrus.TraceLevel) { - return &Authorizer{ - defaultPolicy: PolicyToLevel(configuration.DefaultPolicy), - rules: NewAccessControlRules(configuration), - } - } - +func NewAuthorizer(configuration *schema.Configuration) *Authorizer { return &Authorizer{ - defaultPolicy: PolicyToLevel(configuration.DefaultPolicy), - rules: NewAccessControlRules(configuration), + defaultPolicy: PolicyToLevel(configuration.AccessControl.DefaultPolicy), + rules: NewAccessControlRules(configuration.AccessControl), + configuration: configuration, } } // IsSecondFactorEnabled return true if at least one policy is set to second factor. -func (p *Authorizer) IsSecondFactorEnabled() bool { +func (p Authorizer) IsSecondFactorEnabled() bool { if p.defaultPolicy == TwoFactor { return true } @@ -40,6 +33,14 @@ func (p *Authorizer) IsSecondFactorEnabled() bool { } } + if p.configuration.IdentityProviders.OIDC != nil { + for _, client := range p.configuration.IdentityProviders.OIDC.Clients { + if client.Policy == twoFactor { + return true + } + } + } + return false } diff --git a/internal/authorization/authorizer_test.go b/internal/authorization/authorizer_test.go index 3cb58c6d..ee9417d6 100644 --- a/internal/authorization/authorizer_test.go +++ b/internal/authorization/authorizer_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/authelia/authelia/internal/configuration/schema" @@ -20,8 +21,12 @@ type AuthorizerTester struct { } func NewAuthorizerTester(config schema.AccessControlConfiguration) *AuthorizerTester { + fullConfig := &schema.Configuration{ + AccessControl: config, + } + return &AuthorizerTester{ - NewAuthorizer(config), + NewAuthorizer(fullConfig), } } @@ -102,7 +107,7 @@ var Sally = UserWithIPv6AddressAndGroups func (s *AuthorizerSuite) TestShouldCheckDefaultBypassConfig() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("bypass").Build() + WithDefaultPolicy(bypass).Build() tester.CheckAuthorizations(s.T(), AnonymousUser, "https://public.example.com/", "GET", Bypass) tester.CheckAuthorizations(s.T(), UserWithGroups, "https://public.example.com/", "GET", Bypass) @@ -112,7 +117,7 @@ func (s *AuthorizerSuite) TestShouldCheckDefaultBypassConfig() { func (s *AuthorizerSuite) TestShouldCheckDefaultDeniedConfig() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny").Build() + WithDefaultPolicy(deny).Build() tester.CheckAuthorizations(s.T(), AnonymousUser, "https://public.example.com/", "GET", Denied) tester.CheckAuthorizations(s.T(), UserWithGroups, "https://public.example.com/", "GET", Denied) @@ -122,10 +127,10 @@ func (s *AuthorizerSuite) TestShouldCheckDefaultDeniedConfig() { func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"*.example.com"}, - Policy: "bypass", + Policy: bypass, }). Build() @@ -139,14 +144,14 @@ func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() { func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"{user}.example.com"}, - Policy: "bypass", + Policy: bypass, }). WithRule(schema.ACLRule{ Domains: []string{"{group}.example.com"}, - Policy: "bypass", + Policy: bypass, }). Build() @@ -158,10 +163,10 @@ func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() { func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"*.example.com", "other.com"}, - Policy: "bypass", + Policy: bypass, }). Build() @@ -178,18 +183,18 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() { func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"single.example.com"}, - Policy: "one_factor", + Policy: oneFactor, }). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "two_factor", + Policy: twoFactor, }). WithRule(schema.ACLRule{ Domains: []string{"public.example.com"}, - Policy: "bypass", + Policy: bypass, }). Build() @@ -201,19 +206,19 @@ func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() { func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "bypass", + Policy: bypass, Subjects: [][]string{{"user:john"}}, }). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, }). WithRule(schema.ACLRule{ Domains: []string{"*.example.com"}, - Policy: "two_factor", + Policy: twoFactor, }). Build() @@ -224,10 +229,10 @@ func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() { func (s *AuthorizerSuite) TestShouldCheckUserMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Subjects: [][]string{{"user:john"}}, }). Build() @@ -238,10 +243,10 @@ func (s *AuthorizerSuite) TestShouldCheckUserMatching() { func (s *AuthorizerSuite) TestShouldCheckGroupMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Subjects: [][]string{{"group:admins"}}, }). Build() @@ -252,10 +257,10 @@ func (s *AuthorizerSuite) TestShouldCheckGroupMatching() { func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Subjects: [][]string{{"group:admins"}, {"user:bob"}}, }). Build() @@ -268,10 +273,10 @@ func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Subjects: [][]string{{"group:admins", "user:bob"}, {"group:admins", "group:dev"}}, }). Build() @@ -283,30 +288,30 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckIPMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "bypass", + Policy: bypass, Networks: []string{"192.168.1.8", "10.0.0.8"}, }). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Networks: []string{"10.0.0.7"}, }). WithRule(schema.ACLRule{ Domains: []string{"net.example.com"}, - Policy: "two_factor", + Policy: twoFactor, Networks: []string{"10.0.0.0/8"}, }). WithRule(schema.ACLRule{ Domains: []string{"ipv6.example.com"}, - Policy: "two_factor", + Policy: twoFactor, Networks: []string{"fec0::1/64"}, }). WithRule(schema.ACLRule{ Domains: []string{"ipv6-alt.example.com"}, - Policy: "two_factor", + Policy: twoFactor, Networks: []string{"fec0::1"}, }). Build() @@ -327,20 +332,20 @@ func (s *AuthorizerSuite) TestShouldCheckIPMatching() { func (s *AuthorizerSuite) TestShouldCheckMethodMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "bypass", + Policy: bypass, Methods: []string{"OPTIONS", "HEAD", "GET", "CONNECT", "TRACE"}, }). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Methods: []string{"PUT", "PATCH", "POST"}, }). WithRule(schema.ACLRule{ Domains: []string{"protected.example.com"}, - Policy: "two_factor", + Policy: twoFactor, Methods: []string{"DELETE"}, }). Build() @@ -360,15 +365,15 @@ func (s *AuthorizerSuite) TestShouldCheckMethodMatching() { func (s *AuthorizerSuite) TestShouldCheckResourceMatching() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"resource.example.com"}, - Policy: "bypass", + Policy: bypass, Resources: []string{"^/bypass/[a-z]+$", "^/$", "embedded"}, }). WithRule(schema.ACLRule{ Domains: []string{"resource.example.com"}, - Policy: "one_factor", + Policy: oneFactor, Resources: []string{"^/one_factor/[a-z]+$"}, }). Build() @@ -385,15 +390,15 @@ func (s *AuthorizerSuite) TestShouldCheckResourceMatching() { func (s *AuthorizerSuite) TestShouldMatchAnyDomainIfBlank() { tester := NewAuthorizerBuilder(). WithRule(schema.ACLRule{ - Policy: "bypass", + Policy: bypass, Methods: []string{"OPTIONS", "HEAD", "GET", "CONNECT", "TRACE"}, }). WithRule(schema.ACLRule{ - Policy: "one_factor", + Policy: oneFactor, Methods: []string{"PUT", "PATCH"}, }). WithRule(schema.ACLRule{ - Policy: "two_factor", + Policy: twoFactor, Methods: []string{"DELETE"}, }). Build() @@ -417,41 +422,41 @@ func (s *AuthorizerSuite) TestShouldMatchAnyDomainIfBlank() { func (s *AuthorizerSuite) TestShouldMatchResourceWithSubjectRules() { tester := NewAuthorizerBuilder(). - WithDefaultPolicy("deny"). + WithDefaultPolicy(deny). WithRule(schema.ACLRule{ Domains: []string{"public.example.com"}, Resources: []string{"^/admin/.*$"}, Subjects: [][]string{{"group:admins"}}, - Policy: "one_factor", + Policy: oneFactor, }). WithRule(schema.ACLRule{ Domains: []string{"public.example.com"}, Resources: []string{"^/admin/.*$"}, - Policy: "deny", + Policy: deny, }). WithRule(schema.ACLRule{ Domains: []string{"public.example.com"}, - Policy: "bypass", + Policy: bypass, }). WithRule(schema.ACLRule{ Domains: []string{"public2.example.com"}, Resources: []string{"^/admin/.*$"}, Subjects: [][]string{{"group:admins"}}, - Policy: "bypass", + Policy: bypass, }). WithRule(schema.ACLRule{ Domains: []string{"public2.example.com"}, Resources: []string{"^/admin/.*$"}, - Policy: "deny", + Policy: deny, }). WithRule(schema.ACLRule{ Domains: []string{"public2.example.com"}, - Policy: "bypass", + Policy: bypass, }). WithRule(schema.ACLRule{ Domains: []string{"private.example.com"}, Subjects: [][]string{{"group:admins"}}, - Policy: "two_factor", + Policy: twoFactor, }). Build() @@ -479,10 +484,10 @@ func (s *AuthorizerSuite) TestShouldMatchResourceWithSubjectRules() { } func (s *AuthorizerSuite) TestPolicyToLevel() { - s.Assert().Equal(Bypass, PolicyToLevel("bypass")) - s.Assert().Equal(OneFactor, PolicyToLevel("one_factor")) - s.Assert().Equal(TwoFactor, PolicyToLevel("two_factor")) - s.Assert().Equal(Denied, PolicyToLevel("deny")) + s.Assert().Equal(Bypass, PolicyToLevel(bypass)) + s.Assert().Equal(OneFactor, PolicyToLevel(oneFactor)) + s.Assert().Equal(TwoFactor, PolicyToLevel(twoFactor)) + s.Assert().Equal(Denied, PolicyToLevel(deny)) s.Assert().Equal(Denied, PolicyToLevel("whatever")) } @@ -491,3 +496,103 @@ func TestRunSuite(t *testing.T) { s := AuthorizerSuite{} suite.Run(t, &s) } + +func TestNewAuthorizer(t *testing.T) { + config := &schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: deny, + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: twoFactor, + Subjects: [][]string{ + { + "user:admin", + }, + { + "group:admins", + }, + }, + }, + }, + }, + } + + authorizer := NewAuthorizer(config) + + assert.Equal(t, Denied, authorizer.defaultPolicy) + assert.Equal(t, TwoFactor, authorizer.rules[0].Policy) + + user, ok := authorizer.rules[0].Subjects[0].Subjects[0].(AccessControlUser) + require.True(t, ok) + assert.Equal(t, "admin", user.Name) + + group, ok := authorizer.rules[0].Subjects[1].Subjects[0].(AccessControlGroup) + require.True(t, ok) + assert.Equal(t, "admins", group.Name) +} + +func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) { + config := &schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: deny, + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: oneFactor, + }, + }, + }, + } + + authorizer := NewAuthorizer(config) + assert.False(t, authorizer.IsSecondFactorEnabled()) + + authorizer.rules[0].Policy = TwoFactor + assert.True(t, authorizer.IsSecondFactorEnabled()) +} + +func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) { + config := &schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: deny, + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: oneFactor, + }, + }, + }, + IdentityProviders: schema.IdentityProvidersConfiguration{ + OIDC: &schema.OpenIDConnectConfiguration{ + Clients: []schema.OpenIDConnectClientConfiguration{ + { + Policy: oneFactor, + }, + }, + }, + }, + } + + authorizer := NewAuthorizer(config) + assert.False(t, authorizer.IsSecondFactorEnabled()) + + authorizer.rules[0].Policy = TwoFactor + assert.True(t, authorizer.IsSecondFactorEnabled()) + + authorizer.rules[0].Policy = OneFactor + assert.False(t, authorizer.IsSecondFactorEnabled()) + + config.IdentityProviders.OIDC.Clients[0].Policy = twoFactor + + assert.True(t, authorizer.IsSecondFactorEnabled()) + + authorizer.rules[0].Policy = OneFactor + config.IdentityProviders.OIDC.Clients[0].Policy = oneFactor + + assert.False(t, authorizer.IsSecondFactorEnabled()) + + authorizer.defaultPolicy = TwoFactor + + assert.True(t, authorizer.IsSecondFactorEnabled()) +} diff --git a/internal/authorization/const.go b/internal/authorization/const.go index 8b00cf41..e5023a2f 100644 --- a/internal/authorization/const.go +++ b/internal/authorization/const.go @@ -17,4 +17,9 @@ const ( const userPrefix = "user:" const groupPrefix = "group:" +const bypass = "bypass" +const oneFactor = "one_factor" +const twoFactor = "two_factor" +const deny = "deny" + const traceFmtACLHitMiss = "ACL %s Position %d for subject %s and object %s (Method %s)" diff --git a/internal/authorization/util.go b/internal/authorization/util.go index c258e441..7aeb1ad2 100644 --- a/internal/authorization/util.go +++ b/internal/authorization/util.go @@ -12,13 +12,13 @@ import ( // PolicyToLevel converts a string policy to int authorization level. func PolicyToLevel(policy string) Level { switch policy { - case "bypass": + case bypass: return Bypass - case "one_factor": + case oneFactor: return OneFactor - case "two_factor": + case twoFactor: return TwoFactor - case "deny": + case deny: return Denied } // By default the deny policy applies. diff --git a/internal/handlers/handler_configuration.go b/internal/handlers/handler_configuration.go index b39ef51a..9520c62c 100644 --- a/internal/handlers/handler_configuration.go +++ b/internal/handlers/handler_configuration.go @@ -23,6 +23,7 @@ func ConfigurationGet(ctx *middlewares.AutheliaCtx) { } body.SecondFactorEnabled = ctx.Providers.Authorizer.IsSecondFactorEnabled() + ctx.Logger.Tracef("Second factor enabled: %v", body.SecondFactorEnabled) ctx.Logger.Tracef("Available methods are %s", body.AvailableMethods) diff --git a/internal/handlers/handler_configuration_test.go b/internal/handlers/handler_configuration_test.go index d5e82101..9340584d 100644 --- a/internal/handlers/handler_configuration_test.go +++ b/internal/handlers/handler_configuration_test.go @@ -17,10 +17,11 @@ type SecondFactorAvailableMethodsFixture struct { func (s *SecondFactorAvailableMethodsFixture) SetupTest() { s.mock = mocks.NewMockAutheliaCtx(s.T()) - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "deny", - Rules: []schema.ACLRule{}, - }) + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "deny", + Rules: []schema.ACLRule{}, + }}) } func (s *SecondFactorAvailableMethodsFixture) TearDownTest() { @@ -66,23 +67,25 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsDisab Period: schema.DefaultTOTPConfiguration.Period, }, } - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "bypass", - Rules: []schema.ACLRule{ - { - Domains: []string{"example.com"}, - Policy: "deny", - }, - { - Domains: []string{"abc.example.com"}, - Policy: "single_factor", - }, - { - Domains: []string{"def.example.com"}, - Policy: "bypass", - }, - }, - }) + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer( + &schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "bypass", + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: "deny", + }, + { + Domains: []string{"abc.example.com"}, + Policy: "single_factor", + }, + { + Domains: []string{"def.example.com"}, + Policy: "bypass", + }, + }, + }}) ConfigurationGet(s.mock.Ctx) s.mock.Assert200OK(s.T(), ConfigurationBody{ AvailableMethods: []string{"totp", "u2f"}, @@ -97,23 +100,24 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabl Period: schema.DefaultTOTPConfiguration.Period, }, } - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "two_factor", - Rules: []schema.ACLRule{ - { - Domains: []string{"example.com"}, - Policy: "deny", + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "two_factor", + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: "deny", + }, + { + Domains: []string{"abc.example.com"}, + Policy: "single_factor", + }, + { + Domains: []string{"def.example.com"}, + Policy: "bypass", + }, }, - { - Domains: []string{"abc.example.com"}, - Policy: "single_factor", - }, - { - Domains: []string{"def.example.com"}, - Policy: "bypass", - }, - }, - }) + }}) ConfigurationGet(s.mock.Ctx) s.mock.Assert200OK(s.T(), ConfigurationBody{ AvailableMethods: []string{"totp", "u2f"}, @@ -128,23 +132,25 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabl Period: schema.DefaultTOTPConfiguration.Period, }, } - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "bypass", - Rules: []schema.ACLRule{ - { - Domains: []string{"example.com"}, - Policy: "deny", - }, - { - Domains: []string{"abc.example.com"}, - Policy: "two_factor", - }, - { - Domains: []string{"def.example.com"}, - Policy: "bypass", - }, - }, - }) + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer( + &schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "bypass", + Rules: []schema.ACLRule{ + { + Domains: []string{"example.com"}, + Policy: "deny", + }, + { + Domains: []string{"abc.example.com"}, + Policy: "two_factor", + }, + { + Domains: []string{"def.example.com"}, + Policy: "bypass", + }, + }, + }}) ConfigurationGet(s.mock.Ctx) s.mock.Assert200OK(s.T(), ConfigurationBody{ AvailableMethods: []string{"totp", "u2f"}, diff --git a/internal/handlers/handler_firstfactor_test.go b/internal/handlers/handler_firstfactor_test.go index b78c0de7..0c005e00 100644 --- a/internal/handlers/handler_firstfactor_test.go +++ b/internal/handlers/handler_firstfactor_test.go @@ -288,8 +288,7 @@ func (s *FirstFactorRedirectionSuite) SetupTest() { Policy: "one_factor", }, } - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer( - s.mock.Ctx.Configuration.AccessControl) + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&s.mock.Ctx.Configuration) s.mock.UserProviderMock. EXPECT(). @@ -360,8 +359,10 @@ func (s *FirstFactorRedirectionSuite) TestShouldRedirectToDefaultURLWhenURLIsUns // Then: // the user should receive 200 without redirection URL. func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenNoTargetURLProvidedAndTwoFactorEnabled() { - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "two_factor", + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "two_factor", + }, }) s.mock.Ctx.Request.SetBodyString(`{ "username": "test", @@ -381,19 +382,20 @@ func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenNoTargetURLProvidedA // Then: // the user should receive 200 without redirection URL. func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenUnsafeTargetURLProvidedAndTwoFactorEnabled() { - s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "one_factor", - Rules: []schema.ACLRule{ - { - Domains: []string{"test.example.com"}, - Policy: "one_factor", + s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "one_factor", + Rules: []schema.ACLRule{ + { + Domains: []string{"test.example.com"}, + Policy: "one_factor", + }, + { + Domains: []string{"example.com"}, + Policy: "two_factor", + }, }, - { - Domains: []string{"example.com"}, - Policy: "two_factor", - }, - }, - }) + }}) s.mock.Ctx.Request.SetBodyString(`{ "username": "test", "password": "hello", diff --git a/internal/handlers/handler_verify_test.go b/internal/handlers/handler_verify_test.go index 14238805..f78e91f5 100644 --- a/internal/handlers/handler_verify_test.go +++ b/internal/handlers/handler_verify_test.go @@ -147,13 +147,14 @@ func TestShouldCheckAuthorizationMatching(t *testing.T) { url, _ := url.ParseRequestURI("https://test.example.com") for _, rule := range rules { - authorizer := authorization.NewAuthorizer(schema.AccessControlConfiguration{ - DefaultPolicy: "deny", - Rules: []schema.ACLRule{{ - Domains: []string{"test.example.com"}, - Policy: rule.Policy, - }}, - }) + authorizer := authorization.NewAuthorizer(&schema.Configuration{ + AccessControl: schema.AccessControlConfiguration{ + DefaultPolicy: "deny", + Rules: []schema.ACLRule{{ + Domains: []string{"test.example.com"}, + Policy: rule.Policy, + }}, + }}) username := "" if rule.AuthLevel > authentication.NotAuthenticated { @@ -181,16 +182,6 @@ func TestShouldVerifyWrongCredentials(t *testing.T) { assert.Error(t, err) } -type TestCase struct { - URL string - Authorization string - ExpectedStatusCode int -} - -func (tc TestCase) String() string { - return fmt.Sprintf("url=%s, auth=%s, exp_status=%d", tc.URL, tc.Authorization, tc.ExpectedStatusCode) -} - type BasicAuthorizationSuite struct { suite.Suite } diff --git a/internal/mocks/mock_authelia_ctx.go b/internal/mocks/mock_authelia_ctx.go index 166f3c3b..b308a155 100644 --- a/internal/mocks/mock_authelia_ctx.go +++ b/internal/mocks/mock_authelia_ctx.go @@ -105,7 +105,7 @@ func NewMockAutheliaCtx(t *testing.T) *MockAutheliaCtx { providers.Notifier = mockAuthelia.NotifierMock providers.Authorizer = authorization.NewAuthorizer( - configuration.AccessControl) + &configuration) providers.SessionProvider = session.NewProvider( configuration.Session, nil) diff --git a/internal/suites/scenario_redirection_check_test.go b/internal/suites/scenario_redirection_check_test.go index fc369f65..af5f8b2e 100644 --- a/internal/suites/scenario_redirection_check_test.go +++ b/internal/suites/scenario_redirection_check_test.go @@ -58,7 +58,7 @@ var redirectionAuthorizations = map[string]bool{ } func (s *RedirectionCheckScenario) TestShouldRedirectOnLoginOnlyWhenDomainIsSafe() { - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) defer cancel() secret := s.doRegisterThenLogout(ctx, s.T(), "john", "password") @@ -66,12 +66,13 @@ func (s *RedirectionCheckScenario) TestShouldRedirectOnLoginOnlyWhenDomainIsSafe for url, redirected := range redirectionAuthorizations { s.T().Run(url, func(t *testing.T) { s.doLoginTwoFactor(ctx, t, "john", "password", false, secret, url) - time.Sleep(1 * time.Second) + if redirected { s.verifySecretAuthorized(ctx, t) } else { s.verifyIsAuthenticatedPage(ctx, t) } + s.doLogout(ctx, t) }) }