package embed import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/authelia/authelia/v4/internal/configuration" ) func TestNewConfiguration(t *testing.T) { testCases := []struct { name string paths []string filters []configuration.BytesFilter keys []string warnings []string errors []string err string }{ { name: "ShouldHandleWebAuthn", paths: []string{"../../internal/configuration/test_resources/config.webauthn.yml"}, keys: []string{ "server.endpoints.rate_limits.reset_password_finish.enable", "server.endpoints.rate_limits.reset_password_start.enable", "server.endpoints.rate_limits.second_factor_duo.enable", "server.endpoints.rate_limits.second_factor_totp.enable", "server.endpoints.rate_limits.session_elevation_finish.enable", "server.endpoints.rate_limits.session_elevation_start.enable", "webauthn.selection_criteria.attachment", "webauthn.selection_criteria.discoverability", "webauthn.selection_criteria.user_verification", }, warnings: nil, errors: []string{ "identity_validation: reset_password: option 'jwt_secret' is required when the reset password functionality isn't disabled", "authentication_backend: you must ensure either the 'file' or 'ldap' authentication backend is configured", "access_control: 'default_policy' option 'deny' is invalid: when no rules are specified it must be 'two_factor' or 'one_factor'", "session: option 'cookies' is required", "storage: option 'encryption_key' is required", "storage: configuration for a 'local', 'mysql' or 'postgres' database must be provided", "notifier: you must ensure either the 'smtp' or 'filesystem' notifier is configured", }, }, { name: "ShouldHandleConfigWithDefinitions", paths: []string{"../../internal/configuration/test_resources/config_with_definitions.yml"}, keys: []string{ "access_control.default_policy", "access_control.networks", "access_control.networks[].name", "access_control.networks[].networks", "access_control.rules", "access_control.rules[].domain", "access_control.rules[].networks", "access_control.rules[].policy", "access_control.rules[].resources", "access_control.rules[].subject", "authentication_backend.ldap.additional_groups_dn", "authentication_backend.ldap.additional_users_dn", "authentication_backend.ldap.address", "authentication_backend.ldap.attributes.group_name", "authentication_backend.ldap.attributes.mail", "authentication_backend.ldap.attributes.username", "authentication_backend.ldap.base_dn", "authentication_backend.ldap.groups_filter", "authentication_backend.ldap.tls.private_key", "authentication_backend.ldap.user", "authentication_backend.ldap.users_filter", "authentication_backend.refresh_interval", "definitions.network.lan", "definitions.user_attributes.example.expression", "duo_api.hostname", "duo_api.integration_key", "log.level", "notifier.smtp.address", "notifier.smtp.disable_require_tls", "notifier.smtp.sender", "notifier.smtp.username", "regulation.ban_time", "regulation.find_time", "regulation.max_retries", "server.address", "server.endpoints.authz.auth-request.authn_strategies", "server.endpoints.authz.auth-request.authn_strategies[].name", "server.endpoints.authz.auth-request.implementation", "server.endpoints.authz.ext-authz.authn_strategies", "server.endpoints.authz.ext-authz.authn_strategies[].name", "server.endpoints.authz.ext-authz.implementation", "server.endpoints.authz.forward-auth.authn_strategies", "server.endpoints.authz.forward-auth.authn_strategies[].name", "server.endpoints.authz.forward-auth.implementation", "server.endpoints.authz.legacy.implementation", "server.endpoints.rate_limits.reset_password_finish.enable", "server.endpoints.rate_limits.reset_password_start.enable", "server.endpoints.rate_limits.second_factor_duo.enable", "server.endpoints.rate_limits.second_factor_totp.enable", "server.endpoints.rate_limits.session_elevation_finish.enable", "server.endpoints.rate_limits.session_elevation_start.enable", "session.cookies", "session.cookies[].authelia_url", "session.cookies[].default_redirection_url", "session.cookies[].domain", "session.expiration", "session.inactivity", "session.name", "session.redis.high_availability.sentinel_name", "session.redis.host", "session.redis.port", "storage.mysql.address", "storage.mysql.database", "storage.mysql.username", "totp.issuer", "webauthn.selection_criteria.discoverability", "webauthn.selection_criteria.user_verification", }, warnings: nil, errors: []string{ "duo_api: option 'secret_key' is required when duo is enabled but it's absent", "identity_validation: reset_password: option 'jwt_secret' is required when the reset password functionality isn't disabled", "authentication_backend: ldap: option 'password' is required", "session: option 'secret' is required when using the 'redis' provider", "storage: option 'encryption_key' is required", }, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { t.Run("Individual", func(t *testing.T) { keys, config, val, err := NewConfiguration(tc.paths, tc.filters) assert.Equal(t, tc.keys, keys) if tc.err != "" { assert.EqualError(t, err, tc.err) assert.Nil(t, config) } else { assert.NoError(t, err) assert.NotNil(t, config) ValidateConfigurationKeys(keys, val) ValidateConfiguration(config, val) } require.Len(t, val.Warnings(), len(tc.warnings)) require.Len(t, val.Errors(), len(tc.errors)) for i, err := range val.Warnings() { assert.EqualError(t, err, tc.warnings[i]) } for i, err := range val.Errors() { assert.EqualError(t, err, tc.errors[i]) } }) t.Run("Combined", func(t *testing.T) { keys, config, val, err := NewConfiguration(tc.paths, tc.filters) assert.Equal(t, tc.keys, keys) if tc.err != "" { assert.EqualError(t, err, tc.err) assert.Nil(t, config) } else { assert.NoError(t, err) assert.NotNil(t, config) ValidateConfigurationAndKeys(config, keys, val) } require.Len(t, val.Warnings(), len(tc.warnings)) require.Len(t, val.Errors(), len(tc.errors)) for i, err := range val.Warnings() { assert.EqualError(t, err, tc.warnings[i]) } for i, err := range val.Errors() { assert.EqualError(t, err, tc.errors[i]) } }) }) } } func TestNewNamedConfigFileFilters(t *testing.T) { filters, err := NewNamedConfigFileFilters("abc") assert.Nil(t, filters) assert.EqualError(t, err, "error occurred loading filters: invalid filter named 'abc'") filters, err = NewNamedConfigFileFilters("template") assert.NotNil(t, filters) assert.NoError(t, err) }