mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
fix: removed deprecated smtp/ldap options (#1912)
This removes the deprecated options from 4.25. This includes the LDAP filters which allow {0} or {1} placeholders. The new aliases are documented. Additionally it refactors the keys validator to use uniform messages for most replaced keys.
This commit is contained in:
parent
168dbf7265
commit
cc4f47f21c
|
@ -36,7 +36,7 @@ func startServer() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
autheliaCertPool, errs, nonFatalErrs := utils.NewX509CertPool(config.CertificatesDirectory, config)
|
autheliaCertPool, errs, nonFatalErrs := utils.NewX509CertPool(config.CertificatesDirectory)
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
|
@ -89,8 +89,8 @@ func startServer() {
|
||||||
switch {
|
switch {
|
||||||
case config.AuthenticationBackend.File != nil:
|
case config.AuthenticationBackend.File != nil:
|
||||||
userProvider = authentication.NewFileUserProvider(config.AuthenticationBackend.File)
|
userProvider = authentication.NewFileUserProvider(config.AuthenticationBackend.File)
|
||||||
case config.AuthenticationBackend.Ldap != nil:
|
case config.AuthenticationBackend.LDAP != nil:
|
||||||
userProvider = authentication.NewLDAPUserProvider(*config.AuthenticationBackend.Ldap, autheliaCertPool)
|
userProvider = authentication.NewLDAPUserProvider(*config.AuthenticationBackend.LDAP, autheliaCertPool)
|
||||||
default:
|
default:
|
||||||
logger.Fatalf("Unrecognized authentication backend")
|
logger.Fatalf("Unrecognized authentication backend")
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,6 @@ authentication_backend:
|
||||||
## - {input} is a placeholder replaced by what the user inputs in the login form.
|
## - {input} is a placeholder replaced by what the user inputs in the login form.
|
||||||
## - {username_attribute} is a mandatory placeholder replaced by what is configured in `username_attribute`.
|
## - {username_attribute} is a mandatory placeholder replaced by what is configured in `username_attribute`.
|
||||||
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
||||||
## - DON'T USE - {0} is an alias for {input} supported for backward compatibility but it will be deprecated in later
|
|
||||||
## versions, so please don't use it.
|
|
||||||
##
|
##
|
||||||
## Recommended settings are as follows:
|
## Recommended settings are as follows:
|
||||||
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
|
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
|
||||||
|
@ -185,10 +183,6 @@ authentication_backend:
|
||||||
## - {dn} is a matcher replaced by the user distinguished name, aka, user DN.
|
## - {dn} is a matcher replaced by the user distinguished name, aka, user DN.
|
||||||
## - {username_attribute} is a placeholder replaced by what is configured in `username_attribute`.
|
## - {username_attribute} is a placeholder replaced by what is configured in `username_attribute`.
|
||||||
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
||||||
## - DON'T USE - {0} is an alias for {input} supported for backward compatibility but it will be deprecated in later
|
|
||||||
## versions, so please don't use it.
|
|
||||||
## - DON'T USE - {1} is an alias for {username} supported for backward compatibility but it will be deprecated in
|
|
||||||
## later version, so please don't use it.
|
|
||||||
##
|
##
|
||||||
## If your groups use the `groupOfUniqueNames` structure use this instead:
|
## If your groups use the `groupOfUniqueNames` structure use this instead:
|
||||||
## (&(uniquemember={dn})(objectclass=groupOfUniqueNames))
|
## (&(uniquemember={dn})(objectclass=groupOfUniqueNames))
|
||||||
|
|
|
@ -148,7 +148,11 @@ Similar to [additional_users_dn](#additional_users_dn) but it applies to group s
|
||||||
|
|
||||||
### groups_filter
|
### groups_filter
|
||||||
|
|
||||||
Similar to [users_filter](#users_filter) but it applies to group searches.
|
Similar to [users_filter](#users_filter) but it applies to group searches. In order to include groups the memeber is not
|
||||||
|
a direct member of, but is a member of another group that is a member of those (i.e. recursive groups), you may try
|
||||||
|
using the following filter which is currently only tested against Microsoft Active Directory:
|
||||||
|
|
||||||
|
`(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group)(objectCategory=group))`
|
||||||
|
|
||||||
### mail_attribute
|
### mail_attribute
|
||||||
|
|
||||||
|
|
|
@ -62,27 +62,6 @@ func NewLDAPUserProviderWithFactory(configuration schema.LDAPAuthenticationBacke
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *LDAPUserProvider) parseDynamicConfiguration() {
|
func (p *LDAPUserProvider) parseDynamicConfiguration() {
|
||||||
// Deprecated: This is temporary for deprecation notice purposes. TODO: Remove in 4.28.
|
|
||||||
if strings.Contains(p.configuration.UsersFilter, "{0}") {
|
|
||||||
p.logger.Warnf("DEPRECATION NOTICE: LDAP Users Filter will no longer support replacing `{0}` in 4.28.0. Please use `{input}` instead.")
|
|
||||||
|
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{0}", "{input}")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: This is temporary for deprecation notice purposes. TODO: Remove in 4.28.
|
|
||||||
if strings.Contains(p.configuration.GroupsFilter, "{0}") {
|
|
||||||
p.logger.Warnf("DEPRECATION NOTICE: LDAP Groups Filter will no longer support replacing `{0}` in 4.28.0. Please use `{input}` instead.")
|
|
||||||
|
|
||||||
p.configuration.GroupsFilter = strings.ReplaceAll(p.configuration.GroupsFilter, "{0}", "{input}")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: This is temporary for deprecation notice purposes. TODO: Remove in 4.28.
|
|
||||||
if strings.Contains(p.configuration.GroupsFilter, "{1}") {
|
|
||||||
p.logger.Warnf("DEPRECATION NOTICE: LDAP Groups Filter will no longer support replacing `{1}` in 4.28.0. Please use `{username}` instead.")
|
|
||||||
|
|
||||||
p.configuration.GroupsFilter = strings.ReplaceAll(p.configuration.GroupsFilter, "{1}", "{username}")
|
|
||||||
}
|
|
||||||
|
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{username_attribute}", p.configuration.UsernameAttribute)
|
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{username_attribute}", p.configuration.UsernameAttribute)
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{mail_attribute}", p.configuration.MailAttribute)
|
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{mail_attribute}", p.configuration.MailAttribute)
|
||||||
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{display_name_attribute}", p.configuration.DisplayNameAttribute)
|
p.configuration.UsersFilter = strings.ReplaceAll(p.configuration.UsersFilter, "{display_name_attribute}", p.configuration.DisplayNameAttribute)
|
||||||
|
|
|
@ -713,8 +713,8 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
|
||||||
UsernameAttribute: "uid",
|
UsernameAttribute: "uid",
|
||||||
MailAttribute: "mail",
|
MailAttribute: "mail",
|
||||||
DisplayNameAttribute: "displayname",
|
DisplayNameAttribute: "displayname",
|
||||||
UsersFilter: "(&(|({username_attribute}={0})({mail_attribute}={0})({display_name_attribute}={0}))(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!pwdLastSet=0))",
|
UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input})({display_name_attribute}={input}))(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!pwdLastSet=0))",
|
||||||
GroupsFilter: "(&(|(member={dn})(member={0})(member={1}))(objectClass=group))",
|
GroupsFilter: "(&(|(member={dn})(member={input})(member={username}))(objectClass=group))",
|
||||||
AdditionalUsersDN: "ou=users",
|
AdditionalUsersDN: "ou=users",
|
||||||
AdditionalGroupsDN: "ou=groups",
|
AdditionalGroupsDN: "ou=groups",
|
||||||
BaseDN: "dc=example,dc=com",
|
BaseDN: "dc=example,dc=com",
|
||||||
|
|
|
@ -162,8 +162,6 @@ authentication_backend:
|
||||||
## - {input} is a placeholder replaced by what the user inputs in the login form.
|
## - {input} is a placeholder replaced by what the user inputs in the login form.
|
||||||
## - {username_attribute} is a mandatory placeholder replaced by what is configured in `username_attribute`.
|
## - {username_attribute} is a mandatory placeholder replaced by what is configured in `username_attribute`.
|
||||||
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
||||||
## - DON'T USE - {0} is an alias for {input} supported for backward compatibility but it will be deprecated in later
|
|
||||||
## versions, so please don't use it.
|
|
||||||
##
|
##
|
||||||
## Recommended settings are as follows:
|
## Recommended settings are as follows:
|
||||||
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
|
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
|
||||||
|
@ -185,10 +183,6 @@ authentication_backend:
|
||||||
## - {dn} is a matcher replaced by the user distinguished name, aka, user DN.
|
## - {dn} is a matcher replaced by the user distinguished name, aka, user DN.
|
||||||
## - {username_attribute} is a placeholder replaced by what is configured in `username_attribute`.
|
## - {username_attribute} is a placeholder replaced by what is configured in `username_attribute`.
|
||||||
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
## - {mail_attribute} is a placeholder replaced by what is configured in `mail_attribute`.
|
||||||
## - DON'T USE - {0} is an alias for {input} supported for backward compatibility but it will be deprecated in later
|
|
||||||
## versions, so please don't use it.
|
|
||||||
## - DON'T USE - {1} is an alias for {username} supported for backward compatibility but it will be deprecated in
|
|
||||||
## later version, so please don't use it.
|
|
||||||
##
|
##
|
||||||
## If your groups use the `groupOfUniqueNames` structure use this instead:
|
## If your groups use the `groupOfUniqueNames` structure use this instead:
|
||||||
## (&(uniquemember={dn})(objectclass=groupOfUniqueNames))
|
## (&(uniquemember={dn})(objectclass=groupOfUniqueNames))
|
||||||
|
|
|
@ -195,7 +195,7 @@ func TestShouldParseConfigFile(t *testing.T) {
|
||||||
assert.Equal(t, "duo_secret_from_env", config.DuoAPI.SecretKey)
|
assert.Equal(t, "duo_secret_from_env", config.DuoAPI.SecretKey)
|
||||||
|
|
||||||
assert.Equal(t, "session_secret_from_env", config.Session.Secret)
|
assert.Equal(t, "session_secret_from_env", config.Session.Secret)
|
||||||
assert.Equal(t, "ldap_secret_from_env", config.AuthenticationBackend.Ldap.Password)
|
assert.Equal(t, "ldap_secret_from_env", config.AuthenticationBackend.LDAP.Password)
|
||||||
assert.Equal(t, "smtp_secret_from_env", config.Notifier.SMTP.Password)
|
assert.Equal(t, "smtp_secret_from_env", config.Notifier.SMTP.Password)
|
||||||
assert.Equal(t, "redis_secret_from_env", config.Session.Redis.Password)
|
assert.Equal(t, "redis_secret_from_env", config.Session.Redis.Password)
|
||||||
assert.Equal(t, "redis-sentinel_secret_from_env", config.Session.Redis.HighAvailability.SentinelPassword)
|
assert.Equal(t, "redis-sentinel_secret_from_env", config.Session.Redis.HighAvailability.SentinelPassword)
|
||||||
|
@ -253,7 +253,7 @@ func TestShouldNotParseConfigFileWithOldOrUnexpectedKeys(t *testing.T) {
|
||||||
return errors[i].Error() < errors[j].Error()
|
return errors[i].Error() < errors[j].Error()
|
||||||
})
|
})
|
||||||
assert.EqualError(t, errors[0], "config key not expected: loggy_file")
|
assert.EqualError(t, errors[0], "config key not expected: loggy_file")
|
||||||
assert.EqualError(t, errors[1], "config key replaced: logs_level is now log_level")
|
assert.EqualError(t, errors[1], "invalid configuration key 'logs_level' was replaced by 'log_level'")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldValidateConfigurationTemplate(t *testing.T) {
|
func TestShouldValidateConfigurationTemplate(t *testing.T) {
|
||||||
|
|
|
@ -17,8 +17,6 @@ type LDAPAuthenticationBackendConfiguration struct {
|
||||||
Password string `mapstructure:"password"`
|
Password string `mapstructure:"password"`
|
||||||
StartTLS bool `mapstructure:"start_tls"`
|
StartTLS bool `mapstructure:"start_tls"`
|
||||||
TLS *TLSConfig `mapstructure:"tls"`
|
TLS *TLSConfig `mapstructure:"tls"`
|
||||||
SkipVerify *bool `mapstructure:"skip_verify"` // Deprecated: Replaced with LDAPAuthenticationBackendConfiguration.TLS.SkipVerify. TODO: Remove in 4.28.
|
|
||||||
MinimumTLSVersion string `mapstructure:"minimum_tls_version"` // Deprecated: Replaced with LDAPAuthenticationBackendConfiguration.TLS.MinimumVersion. TODO: Remove in 4.28.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileAuthenticationBackendConfiguration represents the configuration related to file-based backend.
|
// FileAuthenticationBackendConfiguration represents the configuration related to file-based backend.
|
||||||
|
@ -41,7 +39,7 @@ type PasswordConfiguration struct {
|
||||||
type AuthenticationBackendConfiguration struct {
|
type AuthenticationBackendConfiguration struct {
|
||||||
DisableResetPassword bool `mapstructure:"disable_reset_password"`
|
DisableResetPassword bool `mapstructure:"disable_reset_password"`
|
||||||
RefreshInterval string `mapstructure:"refresh_interval"`
|
RefreshInterval string `mapstructure:"refresh_interval"`
|
||||||
Ldap *LDAPAuthenticationBackendConfiguration `mapstructure:"ldap"`
|
LDAP *LDAPAuthenticationBackendConfiguration `mapstructure:"ldap"`
|
||||||
File *FileAuthenticationBackendConfiguration `mapstructure:"file"`
|
File *FileAuthenticationBackendConfiguration `mapstructure:"file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,6 @@ type SMTPNotifierConfiguration struct {
|
||||||
DisableRequireTLS bool `mapstructure:"disable_require_tls"`
|
DisableRequireTLS bool `mapstructure:"disable_require_tls"`
|
||||||
DisableHTMLEmails bool `mapstructure:"disable_html_emails"`
|
DisableHTMLEmails bool `mapstructure:"disable_html_emails"`
|
||||||
TLS *TLSConfig `mapstructure:"tls"`
|
TLS *TLSConfig `mapstructure:"tls"`
|
||||||
TrustedCert string `mapstructure:"trusted_cert"` // Deprecated: Replaced with Global Option CertificatesDirectory. TODO: Remove in 4.28.
|
|
||||||
DisableVerifyCert *bool `mapstructure:"disable_verify_cert"` // Deprecated: Replaced with LDAPAuthenticationBackendConfiguration.TLS.SkipVerify. TODO: Remove in 4.28.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users.
|
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users.
|
||||||
|
|
|
@ -10,6 +10,32 @@ import (
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ValidateAuthenticationBackend validates and update authentication backend configuration.
|
||||||
|
func ValidateAuthenticationBackend(configuration *schema.AuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
||||||
|
if configuration.LDAP == nil && configuration.File == nil {
|
||||||
|
validator.Push(errors.New("Please provide `ldap` or `file` object in `authentication_backend`"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.LDAP != nil && configuration.File != nil {
|
||||||
|
validator.Push(errors.New("You cannot provide both `ldap` and `file` objects in `authentication_backend`"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.File != nil {
|
||||||
|
validateFileAuthenticationBackend(configuration.File, validator)
|
||||||
|
} else if configuration.LDAP != nil {
|
||||||
|
validateLDAPAuthenticationBackend(configuration.LDAP, validator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.RefreshInterval == "" {
|
||||||
|
configuration.RefreshInterval = schema.RefreshIntervalDefault
|
||||||
|
} else {
|
||||||
|
_, err := utils.ParseDurationString(configuration.RefreshInterval)
|
||||||
|
if err != nil && configuration.RefreshInterval != schema.ProfileRefreshDisabled && configuration.RefreshInterval != schema.ProfileRefreshAlways {
|
||||||
|
validator.Push(fmt.Errorf("Auth Backend `refresh_interval` is configured to '%s' but it must be either a duration notation or one of 'disable', or 'always'. Error from parser: %s", configuration.RefreshInterval, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
||||||
func validateFileAuthenticationBackend(configuration *schema.FileAuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
func validateFileAuthenticationBackend(configuration *schema.FileAuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
||||||
if configuration.Path == "" {
|
if configuration.Path == "" {
|
||||||
|
@ -72,14 +98,66 @@ func validateFileAuthenticationBackend(configuration *schema.FileAuthenticationB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateLDAPAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
||||||
|
if configuration.Implementation == "" {
|
||||||
|
configuration.Implementation = schema.DefaultLDAPAuthenticationBackendConfiguration.Implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.TLS == nil {
|
||||||
|
configuration.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.TLS.MinimumVersion == "" {
|
||||||
|
configuration.TLS.MinimumVersion = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS.MinimumVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := utils.TLSStringToTLSConfigVersion(configuration.TLS.MinimumVersion); err != nil {
|
||||||
|
validator.Push(fmt.Errorf("error occurred validating the LDAP minimum_tls_version key with value %s: %v", configuration.TLS.MinimumVersion, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch configuration.Implementation {
|
||||||
|
case schema.LDAPImplementationCustom:
|
||||||
|
setDefaultImplementationCustomLDAPAuthenticationBackend(configuration)
|
||||||
|
case schema.LDAPImplementationActiveDirectory:
|
||||||
|
setDefaultImplementationActiveDirectoryLDAPAuthenticationBackend(configuration)
|
||||||
|
default:
|
||||||
|
validator.Push(fmt.Errorf("authentication backend ldap implementation must be blank or one of the following values `%s`, `%s`", schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory))
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(configuration.UsersFilter, "{0}") {
|
||||||
|
validator.Push(fmt.Errorf("authentication backend ldap users filter must not contain removed placeholders" +
|
||||||
|
", {0} has been replaced with {input}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(configuration.GroupsFilter, "{0}") ||
|
||||||
|
strings.Contains(configuration.GroupsFilter, "{1}") {
|
||||||
|
validator.Push(fmt.Errorf("authentication backend ldap groups filter must not contain removed " +
|
||||||
|
"placeholders, {0} has been replaced with {input} and {1} has been replaced with {username}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.URL == "" {
|
||||||
|
validator.Push(errors.New("Please provide a URL to the LDAP server"))
|
||||||
|
} else {
|
||||||
|
ldapURL, serverName := validateLDAPURL(configuration.URL, validator)
|
||||||
|
|
||||||
|
configuration.URL = ldapURL
|
||||||
|
|
||||||
|
if configuration.TLS.ServerName == "" {
|
||||||
|
configuration.TLS.ServerName = serverName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validateLDAPRequiredParameters(configuration, validator)
|
||||||
|
}
|
||||||
|
|
||||||
// Wrapper for test purposes to exclude the hostname from the return.
|
// Wrapper for test purposes to exclude the hostname from the return.
|
||||||
func validateLdapURLSimple(ldapURL string, validator *schema.StructValidator) (finalURL string) {
|
func validateLDAPURLSimple(ldapURL string, validator *schema.StructValidator) (finalURL string) {
|
||||||
finalURL, _ = validateLdapURL(ldapURL, validator)
|
finalURL, _ = validateLDAPURL(ldapURL, validator)
|
||||||
|
|
||||||
return finalURL
|
return finalURL
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateLdapURL(ldapURL string, validator *schema.StructValidator) (finalURL string, hostname string) {
|
func validateLDAPURL(ldapURL string, validator *schema.StructValidator) (finalURL string, hostname string) {
|
||||||
parsedURL, err := url.Parse(ldapURL)
|
parsedURL, err := url.Parse(ldapURL)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -95,64 +173,7 @@ func validateLdapURL(ldapURL string, validator *schema.StructValidator) (finalUR
|
||||||
return parsedURL.String(), parsedURL.Hostname()
|
return parsedURL.String(), parsedURL.Hostname()
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
func validateLDAPRequiredParameters(configuration *schema.LDAPAuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
||||||
func validateLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
|
||||||
if configuration.Implementation == "" {
|
|
||||||
configuration.Implementation = schema.DefaultLDAPAuthenticationBackendConfiguration.Implementation
|
|
||||||
}
|
|
||||||
|
|
||||||
nilTLS := configuration.TLS == nil
|
|
||||||
if nilTLS {
|
|
||||||
configuration.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated. Maps deprecated values to the new ones. TODO: Remove in 4.28 (if block).
|
|
||||||
if configuration.SkipVerify != nil {
|
|
||||||
validator.PushWarning(errors.New("DEPRECATED: LDAP Auth Backend `skip_verify` option has been replaced by `authentication_backend.ldap.tls.skip_verify` (will be removed in 4.28.0)"))
|
|
||||||
|
|
||||||
if nilTLS {
|
|
||||||
configuration.TLS.SkipVerify = *configuration.SkipVerify
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated. Maps deprecated values to the new ones. TODO: Remove in 4.28 (if block).
|
|
||||||
if configuration.MinimumTLSVersion != "" {
|
|
||||||
validator.PushWarning(errors.New("DEPRECATED: LDAP Auth Backend `minimum_tls_version` option has been replaced by `authentication_backend.ldap.tls.minimum_version` (will be removed in 4.28.0)"))
|
|
||||||
|
|
||||||
if nilTLS {
|
|
||||||
configuration.TLS.MinimumVersion = configuration.MinimumTLSVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.TLS.MinimumVersion == "" {
|
|
||||||
configuration.TLS.MinimumVersion = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS.MinimumVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := utils.TLSStringToTLSConfigVersion(configuration.TLS.MinimumVersion); err != nil {
|
|
||||||
validator.Push(fmt.Errorf("error occurred validating the LDAP minimum_tls_version key with value %s: %v", configuration.TLS.MinimumVersion, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch configuration.Implementation {
|
|
||||||
case schema.LDAPImplementationCustom:
|
|
||||||
setDefaultImplementationCustomLdapAuthenticationBackend(configuration)
|
|
||||||
case schema.LDAPImplementationActiveDirectory:
|
|
||||||
setDefaultImplementationActiveDirectoryLdapAuthenticationBackend(configuration)
|
|
||||||
default:
|
|
||||||
validator.Push(fmt.Errorf("authentication backend ldap implementation must be blank or one of the following values `%s`, `%s`", schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory))
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.URL == "" {
|
|
||||||
validator.Push(errors.New("Please provide a URL to the LDAP server"))
|
|
||||||
} else {
|
|
||||||
ldapURL, serverName := validateLdapURL(configuration.URL, validator)
|
|
||||||
|
|
||||||
configuration.URL = ldapURL
|
|
||||||
|
|
||||||
if configuration.TLS.ServerName == "" {
|
|
||||||
configuration.TLS.ServerName = serverName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: see if it's possible to disable this check if disable_reset_password is set and when anonymous/user binding is supported (#101 and #387)
|
// TODO: see if it's possible to disable this check if disable_reset_password is set and when anonymous/user binding is supported (#101 and #387)
|
||||||
if configuration.User == "" {
|
if configuration.User == "" {
|
||||||
validator.Push(errors.New("Please provide a user name to connect to the LDAP server"))
|
validator.Push(errors.New("Please provide a user name to connect to the LDAP server"))
|
||||||
|
@ -193,7 +214,7 @@ func validateLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDefaultImplementationActiveDirectoryLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration) {
|
func setDefaultImplementationActiveDirectoryLDAPAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration) {
|
||||||
if configuration.UsersFilter == "" {
|
if configuration.UsersFilter == "" {
|
||||||
configuration.UsersFilter = schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter
|
configuration.UsersFilter = schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter
|
||||||
}
|
}
|
||||||
|
@ -219,7 +240,7 @@ func setDefaultImplementationActiveDirectoryLdapAuthenticationBackend(configurat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setDefaultImplementationCustomLdapAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration) {
|
func setDefaultImplementationCustomLDAPAuthenticationBackend(configuration *schema.LDAPAuthenticationBackendConfiguration) {
|
||||||
if configuration.UsernameAttribute == "" {
|
if configuration.UsernameAttribute == "" {
|
||||||
configuration.UsernameAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.UsernameAttribute
|
configuration.UsernameAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.UsernameAttribute
|
||||||
}
|
}
|
||||||
|
@ -236,29 +257,3 @@ func setDefaultImplementationCustomLdapAuthenticationBackend(configuration *sche
|
||||||
configuration.DisplayNameAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.DisplayNameAttribute
|
configuration.DisplayNameAttribute = schema.DefaultLDAPAuthenticationBackendConfiguration.DisplayNameAttribute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateAuthenticationBackend validates and update authentication backend configuration.
|
|
||||||
func ValidateAuthenticationBackend(configuration *schema.AuthenticationBackendConfiguration, validator *schema.StructValidator) {
|
|
||||||
if configuration.Ldap == nil && configuration.File == nil {
|
|
||||||
validator.Push(errors.New("Please provide `ldap` or `file` object in `authentication_backend`"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.Ldap != nil && configuration.File != nil {
|
|
||||||
validator.Push(errors.New("You cannot provide both `ldap` and `file` objects in `authentication_backend`"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.File != nil {
|
|
||||||
validateFileAuthenticationBackend(configuration.File, validator)
|
|
||||||
} else if configuration.Ldap != nil {
|
|
||||||
validateLdapAuthenticationBackend(configuration.Ldap, validator)
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.RefreshInterval == "" {
|
|
||||||
configuration.RefreshInterval = schema.RefreshIntervalDefault
|
|
||||||
} else {
|
|
||||||
_, err := utils.ParseDurationString(configuration.RefreshInterval)
|
|
||||||
if err != nil && configuration.RefreshInterval != schema.ProfileRefreshDisabled && configuration.RefreshInterval != schema.ProfileRefreshAlways {
|
|
||||||
validator.Push(fmt.Errorf("Auth Backend `refresh_interval` is configured to '%s' but it must be either a duration notation or one of 'disable', or 'always'. Error from parser: %s", configuration.RefreshInterval, err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestShouldRaiseErrorWhenBothBackendsProvided(t *testing.T) {
|
||||||
validator := schema.NewStructValidator()
|
validator := schema.NewStructValidator()
|
||||||
backendConfig := schema.AuthenticationBackendConfiguration{}
|
backendConfig := schema.AuthenticationBackendConfiguration{}
|
||||||
|
|
||||||
backendConfig.Ldap = &schema.LDAPAuthenticationBackendConfiguration{}
|
backendConfig.LDAP = &schema.LDAPAuthenticationBackendConfiguration{}
|
||||||
backendConfig.File = &schema.FileAuthenticationBackendConfiguration{
|
backendConfig.File = &schema.FileAuthenticationBackendConfiguration{
|
||||||
Path: "/tmp",
|
Path: "/tmp",
|
||||||
}
|
}
|
||||||
|
@ -202,47 +202,47 @@ func TestFileBasedAuthenticationBackend(t *testing.T) {
|
||||||
suite.Run(t, new(FileBasedAuthenticationBackend))
|
suite.Run(t, new(FileBasedAuthenticationBackend))
|
||||||
}
|
}
|
||||||
|
|
||||||
type LdapAuthenticationBackendSuite struct {
|
type LDAPAuthenticationBackendSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
configuration schema.AuthenticationBackendConfiguration
|
configuration schema.AuthenticationBackendConfiguration
|
||||||
validator *schema.StructValidator
|
validator *schema.StructValidator
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) SetupTest() {
|
func (suite *LDAPAuthenticationBackendSuite) SetupTest() {
|
||||||
suite.validator = schema.NewStructValidator()
|
suite.validator = schema.NewStructValidator()
|
||||||
suite.configuration = schema.AuthenticationBackendConfiguration{}
|
suite.configuration = schema.AuthenticationBackendConfiguration{}
|
||||||
suite.configuration.Ldap = &schema.LDAPAuthenticationBackendConfiguration{}
|
suite.configuration.LDAP = &schema.LDAPAuthenticationBackendConfiguration{}
|
||||||
suite.configuration.Ldap.Implementation = schema.LDAPImplementationCustom
|
suite.configuration.LDAP.Implementation = schema.LDAPImplementationCustom
|
||||||
suite.configuration.Ldap.URL = testLDAPURL
|
suite.configuration.LDAP.URL = testLDAPURL
|
||||||
suite.configuration.Ldap.User = testLDAPUser
|
suite.configuration.LDAP.User = testLDAPUser
|
||||||
suite.configuration.Ldap.Password = testLDAPPassword
|
suite.configuration.LDAP.Password = testLDAPPassword
|
||||||
suite.configuration.Ldap.BaseDN = testLDAPBaseDN
|
suite.configuration.LDAP.BaseDN = testLDAPBaseDN
|
||||||
suite.configuration.Ldap.UsernameAttribute = "uid"
|
suite.configuration.LDAP.UsernameAttribute = "uid"
|
||||||
suite.configuration.Ldap.UsersFilter = "({username_attribute}={input})"
|
suite.configuration.LDAP.UsersFilter = "({username_attribute}={input})"
|
||||||
suite.configuration.Ldap.GroupsFilter = "(cn={input})"
|
suite.configuration.LDAP.GroupsFilter = "(cn={input})"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldValidateCompleteConfiguration() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldValidateCompleteConfiguration() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldValidateDefaultImplementationAndUsernameAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldValidateDefaultImplementationAndUsernameAttribute() {
|
||||||
suite.configuration.Ldap.Implementation = ""
|
suite.configuration.LDAP.Implementation = ""
|
||||||
suite.configuration.Ldap.UsernameAttribute = ""
|
suite.configuration.LDAP.UsernameAttribute = ""
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().Equal(schema.LDAPImplementationCustom, suite.configuration.Ldap.Implementation)
|
suite.Assert().Equal(schema.LDAPImplementationCustom, suite.configuration.LDAP.Implementation)
|
||||||
|
|
||||||
suite.Assert().Equal(suite.configuration.Ldap.UsernameAttribute, schema.DefaultLDAPAuthenticationBackendConfiguration.UsernameAttribute)
|
suite.Assert().Equal(suite.configuration.LDAP.UsernameAttribute, schema.DefaultLDAPAuthenticationBackendConfiguration.UsernameAttribute)
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenImplementationIsInvalidMSAD() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenImplementationIsInvalidMSAD() {
|
||||||
suite.configuration.Ldap.Implementation = "masd"
|
suite.configuration.LDAP.Implementation = "masd"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -252,8 +252,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenImplementat
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication backend ldap implementation must be blank or one of the following values `custom`, `activedirectory`")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication backend ldap implementation must be blank or one of the following values `custom`, `activedirectory`")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvided() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvided() {
|
||||||
suite.configuration.Ldap.URL = ""
|
suite.configuration.LDAP.URL = ""
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
|
@ -262,8 +262,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvi
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a URL to the LDAP server")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a URL to the LDAP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenUserNotProvided() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenUserNotProvided() {
|
||||||
suite.configuration.Ldap.User = ""
|
suite.configuration.LDAP.User = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -273,8 +273,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenUserNotProv
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a user name to connect to the LDAP server")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a user name to connect to the LDAP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenPasswordNotProvided() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenPasswordNotProvided() {
|
||||||
suite.configuration.Ldap.Password = ""
|
suite.configuration.LDAP.Password = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -284,8 +284,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenPasswordNot
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a password to connect to the LDAP server")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a password to connect to the LDAP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenBaseDNNotProvided() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenBaseDNNotProvided() {
|
||||||
suite.configuration.Ldap.BaseDN = ""
|
suite.configuration.LDAP.BaseDN = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -295,8 +295,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseErrorWhenBaseDNNotPr
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a base DN to connect to the LDAP server")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a base DN to connect to the LDAP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnEmptyGroupsFilter() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseOnEmptyGroupsFilter() {
|
||||||
suite.configuration.Ldap.GroupsFilter = ""
|
suite.configuration.LDAP.GroupsFilter = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -306,8 +306,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnEmptyGroupsFilter(
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a groups filter with `groups_filter` attribute")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a groups filter with `groups_filter` attribute")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnEmptyUsersFilter() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseOnEmptyUsersFilter() {
|
||||||
suite.configuration.Ldap.UsersFilter = ""
|
suite.configuration.LDAP.UsersFilter = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -317,8 +317,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnEmptyUsersFilter()
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a users filter with `users_filter` attribute")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Please provide a users filter with `users_filter` attribute")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldNotRaiseOnEmptyUsernameAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotRaiseOnEmptyUsernameAttribute() {
|
||||||
suite.configuration.Ldap.UsernameAttribute = ""
|
suite.configuration.LDAP.UsernameAttribute = ""
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldNotRaiseOnEmptyUsernameAt
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnBadRefreshInterval() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseOnBadRefreshInterval() {
|
||||||
suite.configuration.RefreshInterval = "blah"
|
suite.configuration.RefreshInterval = "blah"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
@ -337,43 +337,60 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseOnBadRefreshInterval
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Auth Backend `refresh_interval` is configured to 'blah' but it must be either a duration notation or one of 'disable', or 'always'. Error from parser: Could not convert the input string of blah into a duration")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Auth Backend `refresh_interval` is configured to 'blah' but it must be either a duration notation or one of 'disable', or 'always'. Error from parser: Could not convert the input string of blah into a duration")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultImplementation() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultImplementation() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal(schema.LDAPImplementationCustom, suite.configuration.Ldap.Implementation)
|
suite.Assert().Equal(schema.LDAPImplementationCustom, suite.configuration.LDAP.Implementation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultGroupNameAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorOnBadFilterPlaceholders() {
|
||||||
|
suite.configuration.LDAP.UsersFilter = "(&({username_attribute}={0})(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
|
||||||
|
suite.configuration.LDAP.GroupsFilter = "(&(member={0})(objectClass=group)(objectCategory=group))"
|
||||||
|
|
||||||
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
|
suite.Assert().True(suite.validator.HasErrors())
|
||||||
|
|
||||||
|
suite.Require().Len(suite.validator.Errors(), 2)
|
||||||
|
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication backend ldap users filter must "+
|
||||||
|
"not contain removed placeholders, {0} has been replaced with {input}")
|
||||||
|
suite.Assert().EqualError(suite.validator.Errors()[1], "authentication backend ldap groups filter must "+
|
||||||
|
"not contain removed placeholders, "+
|
||||||
|
"{0} has been replaced with {input} and {1} has been replaced with {username}")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultGroupNameAttribute() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal("cn", suite.configuration.Ldap.GroupNameAttribute)
|
suite.Assert().Equal("cn", suite.configuration.LDAP.GroupNameAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultMailAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultMailAttribute() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal("mail", suite.configuration.Ldap.MailAttribute)
|
suite.Assert().Equal("mail", suite.configuration.LDAP.MailAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultDisplayNameAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultDisplayNameAttribute() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal("displayname", suite.configuration.Ldap.DisplayNameAttribute)
|
suite.Assert().Equal("displayname", suite.configuration.LDAP.DisplayNameAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultRefreshInterval() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultRefreshInterval() {
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
|
@ -382,8 +399,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldSetDefaultRefreshInterval
|
||||||
suite.Assert().Equal("5m", suite.configuration.RefreshInterval)
|
suite.Assert().Equal("5m", suite.configuration.RefreshInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesNotContainEnclosingParenthesis() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesNotContainEnclosingParenthesis() {
|
||||||
suite.configuration.Ldap.UsersFilter = "{username_attribute}={input}"
|
suite.configuration.LDAP.UsersFilter = "{username_attribute}={input}"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -393,8 +410,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesN
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "The users filter should contain enclosing parenthesis. For instance {username_attribute}={input} should be ({username_attribute}={input})")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "The users filter should contain enclosing parenthesis. For instance {username_attribute}={input} should be ({username_attribute}={input})")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenGroupsFilterDoesNotContainEnclosingParenthesis() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseWhenGroupsFilterDoesNotContainEnclosingParenthesis() {
|
||||||
suite.configuration.Ldap.GroupsFilter = "cn={input}"
|
suite.configuration.LDAP.GroupsFilter = "cn={input}"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -404,8 +421,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenGroupsFilterDoes
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "The groups filter should contain enclosing parenthesis. For instance cn={input} should be (cn={input})")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "The groups filter should contain enclosing parenthesis. For instance cn={input} should be (cn={input})")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesNotContainUsernameAttribute() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesNotContainUsernameAttribute() {
|
||||||
suite.configuration.Ldap.UsersFilter = "(&({mail_attribute}={input})(objectClass=person))"
|
suite.configuration.LDAP.UsersFilter = "(&({mail_attribute}={input})(objectClass=person))"
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
|
@ -414,8 +431,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldRaiseWhenUsersFilterDoesN
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Unable to detect {username_attribute} placeholder in users_filter, your configuration is broken. Please review configuration options listed at https://www.authelia.com/docs/configuration/authentication/ldap.html")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Unable to detect {username_attribute} placeholder in users_filter, your configuration is broken. Please review configuration options listed at https://www.authelia.com/docs/configuration/authentication/ldap.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlaceholder() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlaceholder() {
|
||||||
suite.configuration.Ldap.UsersFilter = "(&({username_attribute}={mail_attribute})(objectClass=person))"
|
suite.configuration.LDAP.UsersFilter = "(&({username_attribute}={mail_attribute})(objectClass=person))"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
|
@ -425,40 +442,42 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlacehol
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Unable to detect {input} placeholder in users_filter, your configuration might be broken. Please review configuration options listed at https://www.authelia.com/docs/configuration/authentication/ldap.html")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Unable to detect {input} placeholder in users_filter, your configuration might be broken. Please review configuration options listed at https://www.authelia.com/docs/configuration/authentication/ldap.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldAdaptLDAPURL() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldAdaptLDAPURL() {
|
||||||
suite.Assert().Equal("", validateLdapURLSimple("127.0.0.1", suite.validator))
|
suite.Assert().Equal("", validateLDAPURLSimple("127.0.0.1", suite.validator))
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Require().Len(suite.validator.Errors(), 1)
|
suite.Require().Len(suite.validator.Errors(), 1)
|
||||||
|
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Unknown scheme for ldap url, should be ldap:// or ldaps://")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Unknown scheme for ldap url, should be ldap:// or ldaps://")
|
||||||
|
|
||||||
suite.Assert().Equal("", validateLdapURLSimple("127.0.0.1:636", suite.validator))
|
suite.Assert().Equal("", validateLDAPURLSimple("127.0.0.1:636", suite.validator))
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Require().Len(suite.validator.Errors(), 2)
|
suite.Require().Len(suite.validator.Errors(), 2)
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[1], "Unable to parse URL to ldap server. The scheme is probably missing: ldap:// or ldaps://")
|
suite.Assert().EqualError(suite.validator.Errors()[1], "Unable to parse URL to ldap server. The scheme is probably missing: ldap:// or ldaps://")
|
||||||
|
|
||||||
suite.Assert().Equal("ldap://127.0.0.1", validateLdapURLSimple("ldap://127.0.0.1", suite.validator))
|
suite.Assert().Equal("ldap://127.0.0.1", validateLDAPURLSimple("ldap://127.0.0.1", suite.validator))
|
||||||
suite.Assert().Equal("ldap://127.0.0.1:390", validateLdapURLSimple("ldap://127.0.0.1:390", suite.validator))
|
suite.Assert().Equal("ldap://127.0.0.1:390", validateLDAPURLSimple("ldap://127.0.0.1:390", suite.validator))
|
||||||
suite.Assert().Equal("ldap://127.0.0.1/abc", validateLdapURLSimple("ldap://127.0.0.1/abc", suite.validator))
|
suite.Assert().Equal("ldap://127.0.0.1/abc", validateLDAPURLSimple("ldap://127.0.0.1/abc", suite.validator))
|
||||||
suite.Assert().Equal("ldap://127.0.0.1/abc?test=abc&x=y", validateLdapURLSimple("ldap://127.0.0.1/abc?test=abc&x=y", suite.validator))
|
suite.Assert().Equal("ldap://127.0.0.1/abc?test=abc&x=y", validateLDAPURLSimple("ldap://127.0.0.1/abc?test=abc&x=y", suite.validator))
|
||||||
|
|
||||||
suite.Assert().Equal("ldaps://127.0.0.1:390", validateLdapURLSimple("ldaps://127.0.0.1:390", suite.validator))
|
suite.Assert().Equal("ldaps://127.0.0.1:390", validateLDAPURLSimple("ldaps://127.0.0.1:390", suite.validator))
|
||||||
suite.Assert().Equal("ldaps://127.0.0.1", validateLdapURLSimple("ldaps://127.0.0.1", suite.validator))
|
suite.Assert().Equal("ldaps://127.0.0.1", validateLDAPURLSimple("ldaps://127.0.0.1", suite.validator))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldDefaultTLS12() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersion() {
|
||||||
|
suite.configuration.LDAP.TLS = &schema.TLSConfig{MinimumVersion: ""}
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasWarnings())
|
suite.Assert().False(suite.validator.HasWarnings())
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal(schema.DefaultLDAPAuthenticationBackendConfiguration.MinimumTLSVersion, suite.configuration.Ldap.MinimumTLSVersion)
|
suite.Assert().Equal(schema.DefaultLDAPAuthenticationBackendConfiguration.TLS.MinimumVersion, suite.configuration.LDAP.TLS.MinimumVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldNotAllowInvalidTLSValue() {
|
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowInvalidTLSValue() {
|
||||||
suite.configuration.Ldap.TLS = &schema.TLSConfig{
|
suite.configuration.LDAP.TLS = &schema.TLSConfig{
|
||||||
MinimumVersion: "SSL2.0",
|
MinimumVersion: "SSL2.0",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,59 +489,8 @@ func (suite *LdapAuthenticationBackendSuite) TestShouldNotAllowInvalidTLSValue()
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "error occurred validating the LDAP minimum_tls_version key with value SSL2.0: supplied TLS version isn't supported")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "error occurred validating the LDAP minimum_tls_version key with value SSL2.0: supplied TLS version isn't supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: Temporary Test. TODO: Remove in 4.28 (Whole Test).
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldReturnDeprecationWarningsAndNoMappingFor428() {
|
|
||||||
var skipVerify = true
|
|
||||||
|
|
||||||
suite.configuration.Ldap.MinimumTLSVersion = "TLS1.0"
|
|
||||||
suite.configuration.Ldap.SkipVerify = &skipVerify
|
|
||||||
suite.configuration.Ldap.TLS = nil
|
|
||||||
suite.configuration.Ldap.TLS = &schema.TLSConfig{
|
|
||||||
ServerName: "golang.org",
|
|
||||||
MinimumVersion: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
|
||||||
|
|
||||||
// Should not override since TLS schema is defined
|
|
||||||
suite.Assert().Equal(false, suite.configuration.Ldap.TLS.SkipVerify)
|
|
||||||
suite.Assert().Equal(schema.DefaultLDAPAuthenticationBackendConfiguration.TLS.MinimumVersion, suite.configuration.Ldap.TLS.MinimumVersion)
|
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
|
||||||
suite.Require().Len(suite.validator.Warnings(), 2)
|
|
||||||
|
|
||||||
warnings := suite.validator.Warnings()
|
|
||||||
|
|
||||||
suite.Assert().EqualError(warnings[0], "DEPRECATED: LDAP Auth Backend `skip_verify` option has been replaced by `authentication_backend.ldap.tls.skip_verify` (will be removed in 4.28.0)")
|
|
||||||
suite.Assert().EqualError(warnings[1], "DEPRECATED: LDAP Auth Backend `minimum_tls_version` option has been replaced by `authentication_backend.ldap.tls.minimum_version` (will be removed in 4.28.0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Temporary Test. TODO: Remove in 4.28 (Whole Test).
|
|
||||||
func (suite *LdapAuthenticationBackendSuite) TestShouldReturnDeprecationWarningsAndMappingFor428() {
|
|
||||||
var skipVerify = true
|
|
||||||
|
|
||||||
tlsVersion := "TLS1.1"
|
|
||||||
|
|
||||||
suite.configuration.Ldap.MinimumTLSVersion = tlsVersion
|
|
||||||
suite.configuration.Ldap.SkipVerify = &skipVerify
|
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
|
||||||
|
|
||||||
// Should override since TLS schema is not defined
|
|
||||||
suite.Assert().Equal(true, suite.configuration.Ldap.TLS.SkipVerify)
|
|
||||||
suite.Assert().Equal(tlsVersion, suite.configuration.Ldap.TLS.MinimumVersion)
|
|
||||||
|
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
|
||||||
suite.Require().Len(suite.validator.Warnings(), 2)
|
|
||||||
|
|
||||||
warnings := suite.validator.Warnings()
|
|
||||||
|
|
||||||
suite.Assert().EqualError(warnings[0], "DEPRECATED: LDAP Auth Backend `skip_verify` option has been replaced by `authentication_backend.ldap.tls.skip_verify` (will be removed in 4.28.0)")
|
|
||||||
suite.Assert().EqualError(warnings[1], "DEPRECATED: LDAP Auth Backend `minimum_tls_version` option has been replaced by `authentication_backend.ldap.tls.minimum_version` (will be removed in 4.28.0)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLdapAuthenticationBackend(t *testing.T) {
|
func TestLdapAuthenticationBackend(t *testing.T) {
|
||||||
suite.Run(t, new(LdapAuthenticationBackendSuite))
|
suite.Run(t, new(LDAPAuthenticationBackendSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActiveDirectoryAuthenticationBackendSuite struct {
|
type ActiveDirectoryAuthenticationBackendSuite struct {
|
||||||
|
@ -534,13 +502,13 @@ type ActiveDirectoryAuthenticationBackendSuite struct {
|
||||||
func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() {
|
func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() {
|
||||||
suite.validator = schema.NewStructValidator()
|
suite.validator = schema.NewStructValidator()
|
||||||
suite.configuration = schema.AuthenticationBackendConfiguration{}
|
suite.configuration = schema.AuthenticationBackendConfiguration{}
|
||||||
suite.configuration.Ldap = &schema.LDAPAuthenticationBackendConfiguration{}
|
suite.configuration.LDAP = &schema.LDAPAuthenticationBackendConfiguration{}
|
||||||
suite.configuration.Ldap.Implementation = schema.LDAPImplementationActiveDirectory
|
suite.configuration.LDAP.Implementation = schema.LDAPImplementationActiveDirectory
|
||||||
suite.configuration.Ldap.URL = testLDAPURL
|
suite.configuration.LDAP.URL = testLDAPURL
|
||||||
suite.configuration.Ldap.User = testLDAPUser
|
suite.configuration.LDAP.User = testLDAPUser
|
||||||
suite.configuration.Ldap.Password = testLDAPPassword
|
suite.configuration.LDAP.Password = testLDAPPassword
|
||||||
suite.configuration.Ldap.BaseDN = testLDAPBaseDN
|
suite.configuration.LDAP.BaseDN = testLDAPBaseDN
|
||||||
suite.configuration.Ldap.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
suite.configuration.LDAP.TLS = schema.DefaultLDAPAuthenticationBackendConfiguration.TLS
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirectoryDefaults() {
|
func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirectoryDefaults() {
|
||||||
|
@ -550,52 +518,52 @@ func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirec
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
suite.Assert().False(suite.validator.HasErrors())
|
||||||
|
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.UsersFilter,
|
suite.configuration.LDAP.UsersFilter,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter)
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.UsernameAttribute,
|
suite.configuration.LDAP.UsernameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsernameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsernameAttribute)
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.DisplayNameAttribute,
|
suite.configuration.LDAP.DisplayNameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.DisplayNameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.DisplayNameAttribute)
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.MailAttribute,
|
suite.configuration.LDAP.MailAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.MailAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.MailAttribute)
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.GroupsFilter,
|
suite.configuration.LDAP.GroupsFilter,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupsFilter)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupsFilter)
|
||||||
suite.Assert().Equal(
|
suite.Assert().Equal(
|
||||||
suite.configuration.Ldap.GroupNameAttribute,
|
suite.configuration.LDAP.GroupNameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupNameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupNameAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldOnlySetDefaultsIfNotManuallyConfigured() {
|
func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldOnlySetDefaultsIfNotManuallyConfigured() {
|
||||||
suite.configuration.Ldap.UsersFilter = "(&({username_attribute}={input})(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
|
suite.configuration.LDAP.UsersFilter = "(&({username_attribute}={input})(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
|
||||||
suite.configuration.Ldap.UsernameAttribute = "cn"
|
suite.configuration.LDAP.UsernameAttribute = "cn"
|
||||||
suite.configuration.Ldap.MailAttribute = "userPrincipalName"
|
suite.configuration.LDAP.MailAttribute = "userPrincipalName"
|
||||||
suite.configuration.Ldap.DisplayNameAttribute = "name"
|
suite.configuration.LDAP.DisplayNameAttribute = "name"
|
||||||
suite.configuration.Ldap.GroupsFilter = "(&(member={dn})(objectClass=group)(objectCategory=group))"
|
suite.configuration.LDAP.GroupsFilter = "(&(member={dn})(objectClass=group)(objectCategory=group))"
|
||||||
suite.configuration.Ldap.GroupNameAttribute = "distinguishedName"
|
suite.configuration.LDAP.GroupNameAttribute = "distinguishedName"
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
ValidateAuthenticationBackend(&suite.configuration, suite.validator)
|
||||||
|
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.UsersFilter,
|
suite.configuration.LDAP.UsersFilter,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsersFilter)
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.UsernameAttribute,
|
suite.configuration.LDAP.UsernameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsernameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.UsernameAttribute)
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.DisplayNameAttribute,
|
suite.configuration.LDAP.DisplayNameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.DisplayNameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.DisplayNameAttribute)
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.MailAttribute,
|
suite.configuration.LDAP.MailAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.MailAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.MailAttribute)
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.GroupsFilter,
|
suite.configuration.LDAP.GroupsFilter,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupsFilter)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupsFilter)
|
||||||
suite.Assert().NotEqual(
|
suite.Assert().NotEqual(
|
||||||
suite.configuration.Ldap.GroupNameAttribute,
|
suite.configuration.LDAP.GroupNameAttribute,
|
||||||
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupNameAttribute)
|
schema.DefaultLDAPAuthenticationBackendImplementationActiveDirectoryConfiguration.GroupNameAttribute)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ const (
|
||||||
errFmtSessionRedisPortRange = "The port must be between 1 and 65535 for the %s session provider"
|
errFmtSessionRedisPortRange = "The port must be between 1 and 65535 for the %s session provider"
|
||||||
errFmtSessionRedisHostRequired = "The host must be provided when using the %s session provider"
|
errFmtSessionRedisHostRequired = "The host must be provided when using the %s session provider"
|
||||||
errFmtSessionRedisHostOrNodesRequired = "Either the host or a node must be provided when using the %s session provider"
|
errFmtSessionRedisHostOrNodesRequired = "Either the host or a node must be provided when using the %s session provider"
|
||||||
|
errFmtReplacedConfigurationKey = "invalid configuration key '%s' was replaced by '%s'"
|
||||||
|
|
||||||
errFileHashing = "config key incorrect: authentication_backend.file.hashing should be authentication_backend.file.password"
|
errFileHashing = "config key incorrect: authentication_backend.file.hashing should be authentication_backend.file.password"
|
||||||
errFilePHashing = "config key incorrect: authentication_backend.file.password_hashing should be authentication_backend.file.password"
|
errFilePHashing = "config key incorrect: authentication_backend.file.password_hashing should be authentication_backend.file.password"
|
||||||
|
@ -138,12 +139,10 @@ var validKeys = []string{
|
||||||
"notifier.smtp.subject",
|
"notifier.smtp.subject",
|
||||||
"notifier.smtp.startup_check_address",
|
"notifier.smtp.startup_check_address",
|
||||||
"notifier.smtp.disable_require_tls",
|
"notifier.smtp.disable_require_tls",
|
||||||
"notifier.smtp.trusted_cert", // TODO: Deprecated: Remove in 4.28.
|
|
||||||
"notifier.smtp.disable_html_emails",
|
"notifier.smtp.disable_html_emails",
|
||||||
"notifier.smtp.tls.minimum_version",
|
"notifier.smtp.tls.minimum_version",
|
||||||
"notifier.smtp.tls.skip_verify",
|
"notifier.smtp.tls.skip_verify",
|
||||||
"notifier.smtp.tls.server_name",
|
"notifier.smtp.tls.server_name",
|
||||||
"notifier.smtp.disable_verify_cert", // TODO: Deprecated: Remove in 4.28.
|
|
||||||
|
|
||||||
// Regulation Keys.
|
// Regulation Keys.
|
||||||
"regulation.max_retries",
|
"regulation.max_retries",
|
||||||
|
@ -175,8 +174,6 @@ var validKeys = []string{
|
||||||
"authentication_backend.ldap.tls.minimum_version",
|
"authentication_backend.ldap.tls.minimum_version",
|
||||||
"authentication_backend.ldap.tls.skip_verify",
|
"authentication_backend.ldap.tls.skip_verify",
|
||||||
"authentication_backend.ldap.tls.server_name",
|
"authentication_backend.ldap.tls.server_name",
|
||||||
"authentication_backend.ldap.skip_verify", // TODO: Deprecated: Remove in 4.28.
|
|
||||||
"authentication_backend.ldap.minimum_tls_version", // TODO: Deprecated: Remove in 4.28.
|
|
||||||
|
|
||||||
// File Authentication Backend Keys.
|
// File Authentication Backend Keys.
|
||||||
"authentication_backend.file.path",
|
"authentication_backend.file.path",
|
||||||
|
@ -188,10 +185,19 @@ var validKeys = []string{
|
||||||
"authentication_backend.file.password.parallelism",
|
"authentication_backend.file.password.parallelism",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var replacedKeys = map[string]string{
|
||||||
|
"authentication_backend.ldap.skip_verify": "authentication_backend.ldap.tls.skip_verify",
|
||||||
|
"authentication_backend.ldap.minimum_tls_version": "authentication_backend.ldap.tls.minimum_version",
|
||||||
|
"notifier.smtp.disable_verify_cert": "notifier.smtp.tls.skip_verify",
|
||||||
|
"logs_file_path": "log_file",
|
||||||
|
"logs_level": "log_level",
|
||||||
|
}
|
||||||
|
|
||||||
var specificErrorKeys = map[string]string{
|
var specificErrorKeys = map[string]string{
|
||||||
"logs_file_path": "config key replaced: logs_file is now log_file",
|
|
||||||
"logs_level": "config key replaced: logs_level is now log_level",
|
|
||||||
"google_analytics": "config key removed: google_analytics - this functionality has been deprecated",
|
"google_analytics": "config key removed: google_analytics - this functionality has been deprecated",
|
||||||
|
"notifier.smtp.trusted_cert": "invalid configuration key `notifier.smtp.trusted_cert` it has been removed, " +
|
||||||
|
"option has been replaced by the global option `certificates_directory`",
|
||||||
|
|
||||||
"authentication_backend.file.password_options.algorithm": errFilePOptions,
|
"authentication_backend.file.password_options.algorithm": errFilePOptions,
|
||||||
"authentication_backend.file.password_options.iterations": errFilePOptions,
|
"authentication_backend.file.password_options.iterations": errFilePOptions,
|
||||||
"authentication_backend.file.password_options.key_length": errFilePOptions,
|
"authentication_backend.file.password_options.key_length": errFilePOptions,
|
||||||
|
|
|
@ -21,6 +21,11 @@ func ValidateKeys(validator *schema.StructValidator, keys []string) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newKey, ok := replacedKeys[key]; ok {
|
||||||
|
validator.Push(fmt.Errorf(errFmtReplacedConfigurationKey, key, newKey))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err, ok := specificErrorKeys[key]; ok {
|
if err, ok := specificErrorKeys[key]; ok {
|
||||||
if !utils.IsStringInSlice(err, errStrings) {
|
if !utils.IsStringInSlice(err, errStrings) {
|
||||||
errStrings = append(errStrings, err)
|
errStrings = append(errStrings, err)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -62,8 +63,8 @@ func TestAllSpecificErrorKeys(t *testing.T) {
|
||||||
|
|
||||||
func TestSpecificErrorKeys(t *testing.T) {
|
func TestSpecificErrorKeys(t *testing.T) {
|
||||||
configKeys := []string{
|
configKeys := []string{
|
||||||
"logs_level",
|
"notifier.smtp.trusted_cert",
|
||||||
"logs_file_path",
|
"google_analytics",
|
||||||
"authentication_backend.file.password_options.algorithm",
|
"authentication_backend.file.password_options.algorithm",
|
||||||
"authentication_backend.file.password_options.iterations", // This should not show another error since our target for the specific error is password_options.
|
"authentication_backend.file.password_options.iterations", // This should not show another error since our target for the specific error is password_options.
|
||||||
"authentication_backend.file.password_hashing.algorithm",
|
"authentication_backend.file.password_hashing.algorithm",
|
||||||
|
@ -77,9 +78,49 @@ func TestSpecificErrorKeys(t *testing.T) {
|
||||||
|
|
||||||
require.Len(t, errs, 5)
|
require.Len(t, errs, 5)
|
||||||
|
|
||||||
assert.EqualError(t, errs[0], specificErrorKeys["logs_level"])
|
assert.EqualError(t, errs[0], specificErrorKeys["notifier.smtp.trusted_cert"])
|
||||||
assert.EqualError(t, errs[1], specificErrorKeys["logs_file_path"])
|
assert.EqualError(t, errs[1], specificErrorKeys["google_analytics"])
|
||||||
assert.EqualError(t, errs[2], specificErrorKeys["authentication_backend.file.password_options.iterations"])
|
assert.EqualError(t, errs[2], specificErrorKeys["authentication_backend.file.password_options.iterations"])
|
||||||
assert.EqualError(t, errs[3], specificErrorKeys["authentication_backend.file.password_hashing.algorithm"])
|
assert.EqualError(t, errs[3], specificErrorKeys["authentication_backend.file.password_hashing.algorithm"])
|
||||||
assert.EqualError(t, errs[4], specificErrorKeys["authentication_backend.file.hashing.algorithm"])
|
assert.EqualError(t, errs[4], specificErrorKeys["authentication_backend.file.hashing.algorithm"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplacedErrors(t *testing.T) {
|
||||||
|
configKeys := []string{
|
||||||
|
"authentication_backend.ldap.skip_verify",
|
||||||
|
"authentication_backend.ldap.minimum_tls_version",
|
||||||
|
"notifier.smtp.disable_verify_cert",
|
||||||
|
"logs_file_path",
|
||||||
|
"logs_level",
|
||||||
|
}
|
||||||
|
|
||||||
|
val := schema.NewStructValidator()
|
||||||
|
ValidateKeys(val, configKeys)
|
||||||
|
|
||||||
|
warns := val.Warnings()
|
||||||
|
errs := val.Errors()
|
||||||
|
|
||||||
|
assert.Len(t, warns, 0)
|
||||||
|
require.Len(t, errs, 5)
|
||||||
|
|
||||||
|
assert.EqualError(t, errs[0], fmt.Sprintf(errFmtReplacedConfigurationKey, "authentication_backend.ldap.skip_verify", "authentication_backend.ldap.tls.skip_verify"))
|
||||||
|
assert.EqualError(t, errs[1], fmt.Sprintf(errFmtReplacedConfigurationKey, "authentication_backend.ldap.minimum_tls_version", "authentication_backend.ldap.tls.minimum_version"))
|
||||||
|
assert.EqualError(t, errs[2], fmt.Sprintf(errFmtReplacedConfigurationKey, "notifier.smtp.disable_verify_cert", "notifier.smtp.tls.skip_verify"))
|
||||||
|
assert.EqualError(t, errs[3], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_file_path", "log_file"))
|
||||||
|
assert.EqualError(t, errs[4], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_level", "log_level"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSecretKeysDontRaiseErrors(t *testing.T) {
|
||||||
|
configKeys := []string{}
|
||||||
|
|
||||||
|
for _, key := range SecretNames {
|
||||||
|
configKeys = append(configKeys, SecretNameToEnvName(key))
|
||||||
|
configKeys = append(configKeys, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
val := schema.NewStructValidator()
|
||||||
|
ValidateKeys(val, configKeys)
|
||||||
|
|
||||||
|
assert.Len(t, val.Warnings(), 0)
|
||||||
|
assert.Len(t, val.Errors(), 0)
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,17 @@
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ValidateNotifier validates and update notifier configuration.
|
// ValidateNotifier validates and update notifier configuration.
|
||||||
//nolint:gocyclo // TODO: Remove in 4.28. Should be able to remove this during the removal of deprecated config.
|
|
||||||
func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *schema.StructValidator) {
|
func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *schema.StructValidator) {
|
||||||
if configuration.SMTP == nil && configuration.FileSystem == nil {
|
if configuration.SMTP == nil && configuration.FileSystem == nil ||
|
||||||
|
configuration.SMTP != nil && configuration.FileSystem != nil {
|
||||||
validator.Push(fmt.Errorf("Notifier should be either `smtp` or `filesystem`"))
|
validator.Push(fmt.Errorf("Notifier should be either `smtp` or `filesystem`"))
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.SMTP != nil && configuration.FileSystem != nil {
|
|
||||||
validator.Push(fmt.Errorf("Notifier should be either `smtp` or `filesystem`"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,51 +23,39 @@ func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *sc
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.SMTP != nil {
|
validateSMTPNotifier(configuration.SMTP, validator)
|
||||||
if configuration.SMTP.StartupCheckAddress == "" {
|
}
|
||||||
configuration.SMTP.StartupCheckAddress = "test@authelia.com"
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.SMTP.Host == "" {
|
func validateSMTPNotifier(configuration *schema.SMTPNotifierConfiguration, validator *schema.StructValidator) {
|
||||||
validator.Push(fmt.Errorf("Host of SMTP notifier must be provided"))
|
if configuration.StartupCheckAddress == "" {
|
||||||
}
|
configuration.StartupCheckAddress = "test@authelia.com"
|
||||||
|
}
|
||||||
|
|
||||||
if configuration.SMTP.Port == 0 {
|
if configuration.Host == "" {
|
||||||
validator.Push(fmt.Errorf("Port of SMTP notifier must be provided"))
|
validator.Push(fmt.Errorf("Host of SMTP notifier must be provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.SMTP.Sender == "" {
|
if configuration.Port == 0 {
|
||||||
validator.Push(fmt.Errorf("Sender of SMTP notifier must be provided"))
|
validator.Push(fmt.Errorf("Port of SMTP notifier must be provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.SMTP.Subject == "" {
|
if configuration.Sender == "" {
|
||||||
configuration.SMTP.Subject = schema.DefaultSMTPNotifierConfiguration.Subject
|
validator.Push(fmt.Errorf("Sender of SMTP notifier must be provided"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.SMTP.Identifier == "" {
|
if configuration.Subject == "" {
|
||||||
configuration.SMTP.Identifier = schema.DefaultSMTPNotifierConfiguration.Identifier
|
configuration.Subject = schema.DefaultSMTPNotifierConfiguration.Subject
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.SMTP.TLS == nil {
|
if configuration.Identifier == "" {
|
||||||
configuration.SMTP.TLS = schema.DefaultSMTPNotifierConfiguration.TLS
|
configuration.Identifier = schema.DefaultSMTPNotifierConfiguration.Identifier
|
||||||
|
}
|
||||||
|
|
||||||
// Deprecated. Maps deprecated values to the new ones. TODO: Remove in 4.28.
|
if configuration.TLS == nil {
|
||||||
if configuration.SMTP.DisableVerifyCert != nil {
|
configuration.TLS = schema.DefaultSMTPNotifierConfiguration.TLS
|
||||||
validator.PushWarning(errors.New("DEPRECATED: SMTP Notifier `disable_verify_cert` option has been replaced by `notifier.smtp.tls.skip_verify` (will be removed in 4.28.0)"))
|
}
|
||||||
|
|
||||||
configuration.SMTP.TLS.SkipVerify = *configuration.SMTP.DisableVerifyCert
|
if configuration.TLS.ServerName == "" {
|
||||||
}
|
configuration.TLS.ServerName = configuration.Host
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated. Maps deprecated values to the new ones. TODO: Remove in 4.28.
|
|
||||||
if configuration.SMTP.TrustedCert != "" {
|
|
||||||
validator.PushWarning(errors.New("DEPRECATED: SMTP Notifier `trusted_cert` option has been replaced by the global option `certificates_directory` (will be removed in 4.28.0)"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.SMTP.TLS.ServerName == "" {
|
|
||||||
configuration.SMTP.TLS.ServerName = configuration.SMTP.Host
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,29 +127,6 @@ func (suite *NotifierSuite) TestShouldEnsureSenderOfSMTPNotifierAreProvided() {
|
||||||
suite.Assert().EqualError(suite.validator.Errors()[0], "Sender of SMTP notifier must be provided")
|
suite.Assert().EqualError(suite.validator.Errors()[0], "Sender of SMTP notifier must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: Temporary Test. TODO: Remove in 4.28 (Whole Test).
|
|
||||||
func (suite *NotifierSuite) TestShouldReturnDeprecationWarningsFor428() {
|
|
||||||
var disableVerifyCert = true
|
|
||||||
|
|
||||||
suite.configuration.SMTP.TrustedCert = "/tmp"
|
|
||||||
suite.configuration.SMTP.DisableVerifyCert = &disableVerifyCert
|
|
||||||
|
|
||||||
ValidateNotifier(&suite.configuration, suite.validator)
|
|
||||||
|
|
||||||
suite.Require().True(suite.validator.HasWarnings())
|
|
||||||
suite.Assert().False(suite.validator.HasErrors())
|
|
||||||
|
|
||||||
warnings := suite.validator.Warnings()
|
|
||||||
|
|
||||||
suite.Require().Len(warnings, 2)
|
|
||||||
|
|
||||||
suite.Assert().EqualError(warnings[0], "DEPRECATED: SMTP Notifier `disable_verify_cert` option has been replaced by `notifier.smtp.tls.skip_verify` (will be removed in 4.28.0)")
|
|
||||||
suite.Assert().EqualError(warnings[1], "DEPRECATED: SMTP Notifier `trusted_cert` option has been replaced by the global option `certificates_directory` (will be removed in 4.28.0)")
|
|
||||||
|
|
||||||
// Should override since TLS schema is not defined
|
|
||||||
suite.Assert().Equal(true, suite.configuration.SMTP.TLS.SkipVerify)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNotifierSuite(t *testing.T) {
|
func TestNotifierSuite(t *testing.T) {
|
||||||
suite.Run(t, new(NotifierSuite))
|
suite.Run(t, new(NotifierSuite))
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ func ValidateSecrets(configuration *schema.Configuration, validator *schema.Stru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.AuthenticationBackend.Ldap != nil {
|
if configuration.AuthenticationBackend.LDAP != nil {
|
||||||
configuration.AuthenticationBackend.Ldap.Password = getSecretValue(SecretNames["LDAPPassword"], validator, viper)
|
configuration.AuthenticationBackend.LDAP.Password = getSecretValue(SecretNames["LDAPPassword"], validator, viper)
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.Notifier != nil && configuration.Notifier.SMTP != nil {
|
if configuration.Notifier != nil && configuration.Notifier.SMTP != nil {
|
||||||
|
|
|
@ -402,7 +402,7 @@ func verifySessionHasUpToDateProfile(ctx *middlewares.AutheliaCtx, targetURL *ur
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProfileRefreshSettings(cfg schema.AuthenticationBackendConfiguration) (refresh bool, refreshInterval time.Duration) {
|
func getProfileRefreshSettings(cfg schema.AuthenticationBackendConfiguration) (refresh bool, refreshInterval time.Duration) {
|
||||||
if cfg.Ldap != nil {
|
if cfg.LDAP != nil {
|
||||||
if cfg.RefreshInterval == schema.ProfileRefreshDisabled {
|
if cfg.RefreshInterval == schema.ProfileRefreshDisabled {
|
||||||
refresh = false
|
refresh = false
|
||||||
refreshInterval = 0
|
refreshInterval = 0
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
|
|
||||||
var verifyGetCfg = schema.AuthenticationBackendConfiguration{
|
var verifyGetCfg = schema.AuthenticationBackendConfiguration{
|
||||||
RefreshInterval: schema.RefreshIntervalDefault,
|
RefreshInterval: schema.RefreshIntervalDefault,
|
||||||
Ldap: &schema.LDAPAuthenticationBackendConfiguration{},
|
LDAP: &schema.LDAPAuthenticationBackendConfiguration{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test getOriginalURL.
|
// Test getOriginalURL.
|
||||||
|
|
|
@ -27,9 +27,8 @@ func NewTLSConfig(config *schema.TLSConfig, defaultMinVersion uint16, certPool *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo // TODO: Remove in 4.28. Should be able to remove the nolint during the removal of deprecated config.
|
|
||||||
// NewX509CertPool generates a x509.CertPool from the system PKI and the directory specified.
|
// NewX509CertPool generates a x509.CertPool from the system PKI and the directory specified.
|
||||||
func NewX509CertPool(directory string, config *schema.Configuration) (certPool *x509.CertPool, errors []error, nonFatalErrors []error) {
|
func NewX509CertPool(directory string) (certPool *x509.CertPool, errors []error, nonFatalErrors []error) {
|
||||||
certPool, err := x509.SystemCertPool()
|
certPool, err := x509.SystemCertPool()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
nonFatalErrors = append(nonFatalErrors, fmt.Errorf("could not load system certificate pool which may result in untrusted certificate issues: %v", err))
|
nonFatalErrors = append(nonFatalErrors, fmt.Errorf("could not load system certificate pool which may result in untrusted certificate issues: %v", err))
|
||||||
|
@ -66,22 +65,6 @@ func NewX509CertPool(directory string, config *schema.Configuration) (certPool *
|
||||||
|
|
||||||
logger.Tracef("Finished scan of directory %s for certificates", directory)
|
logger.Tracef("Finished scan of directory %s for certificates", directory)
|
||||||
|
|
||||||
// Deprecated. Maps deprecated values to the new ones. TODO: Remove in 4.28.
|
|
||||||
if config != nil && config.Notifier != nil && config.Notifier.SMTP != nil && config.Notifier.SMTP.TrustedCert != "" {
|
|
||||||
nonFatalErrors = append(nonFatalErrors, fmt.Errorf("defining the trusted cert in the SMTP notifier is deprecated and will be removed in 4.28.0, please use the global certificates_directory instead"))
|
|
||||||
|
|
||||||
if exists, _ := FileExists(config.Notifier.SMTP.TrustedCert); exists {
|
|
||||||
pem, err := ioutil.ReadFile(config.Notifier.SMTP.TrustedCert)
|
|
||||||
if err != nil {
|
|
||||||
errors = append(errors, fmt.Errorf("failed to read legacy SMTP trusted_cert (see the new certificates_directory option) certificate %s with error: %s", config.Notifier.SMTP.TrustedCert, err))
|
|
||||||
} else if ok := certPool.AppendCertsFromPEM(pem); !ok {
|
|
||||||
errors = append(errors, fmt.Errorf("could not import legacy SMTP trusted_cert (see the new certificates_directory option) certificate %s", config.Notifier.SMTP.TrustedCert))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errors = append(errors, fmt.Errorf("could not import legacy SMTP trusted_cert (see the new certificates_directory option) certificate %s (file does not exist)", config.Notifier.SMTP.TrustedCert))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return certPool, errors, nonFatalErrors
|
return certPool, errors, nonFatalErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ func TestShouldReturnZeroAndErrorOnInvalidTLSVersions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
||||||
pool, errs, nonFatalErrs := NewX509CertPool("/tmp/asdfzyxabc123/not/a/real/dir", nil)
|
pool, errs, nonFatalErrs := NewX509CertPool("/tmp/asdfzyxabc123/not/a/real/dir")
|
||||||
assert.NotNil(t, pool)
|
assert.NotNil(t, pool)
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
if runtime.GOOS == windows {
|
||||||
|
@ -97,7 +97,7 @@ func TestShouldReturnErrWhenX509DirectoryNotExist(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) {
|
func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) {
|
||||||
pool, errs, nonFatalErrs := NewX509CertPool("/tmp", nil)
|
pool, errs, nonFatalErrs := NewX509CertPool("/tmp")
|
||||||
assert.NotNil(t, pool)
|
assert.NotNil(t, pool)
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
if runtime.GOOS == windows {
|
||||||
|
@ -110,64 +110,8 @@ func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) {
|
||||||
assert.Len(t, errs, 0)
|
assert.Len(t, errs, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldRaiseNonFatalErrWhenNotifierTrustedCertConfigured(t *testing.T) {
|
|
||||||
config := &schema.Configuration{
|
|
||||||
Notifier: &schema.NotifierConfiguration{
|
|
||||||
SMTP: &schema.SMTPNotifierConfiguration{
|
|
||||||
TrustedCert: "../suites/common/ssl/cert.pem",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pool, errs, nonFatalErrs := NewX509CertPool("/tmp", config)
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
|
||||||
require.Len(t, nonFatalErrs, 2)
|
|
||||||
assert.EqualError(t, nonFatalErrs[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
|
||||||
|
|
||||||
index = 1
|
|
||||||
} else {
|
|
||||||
require.Len(t, nonFatalErrs, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Len(t, errs, 0)
|
|
||||||
assert.EqualError(t, nonFatalErrs[index], "defining the trusted cert in the SMTP notifier is deprecated and will be removed in 4.28.0, please use the global certificates_directory instead")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldRaiseErrAndNonFatalErrWhenNotifierTrustedCertConfiguredAndNotExist(t *testing.T) {
|
|
||||||
config := &schema.Configuration{
|
|
||||||
Notifier: &schema.NotifierConfiguration{
|
|
||||||
SMTP: &schema.SMTPNotifierConfiguration{
|
|
||||||
TrustedCert: "/tmp/asdfzyxabc123/not/a/real/cert.pem",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
pool, errs, nonFatalErrs := NewX509CertPool("/tmp", config)
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
|
|
||||||
if runtime.GOOS == windows {
|
|
||||||
require.Len(t, nonFatalErrs, 2)
|
|
||||||
assert.EqualError(t, nonFatalErrs[0], "could not load system certificate pool which may result in untrusted certificate issues: crypto/x509: system root pool is not available on Windows")
|
|
||||||
|
|
||||||
index = 1
|
|
||||||
} else {
|
|
||||||
require.Len(t, nonFatalErrs, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
require.Len(t, errs, 1)
|
|
||||||
|
|
||||||
assert.EqualError(t, errs[0], "could not import legacy SMTP trusted_cert (see the new certificates_directory option) certificate /tmp/asdfzyxabc123/not/a/real/cert.pem (file does not exist)")
|
|
||||||
assert.EqualError(t, nonFatalErrs[index], "defining the trusted cert in the SMTP notifier is deprecated and will be removed in 4.28.0, please use the global certificates_directory instead")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) {
|
func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) {
|
||||||
pool, errs, nonFatalErrs := NewX509CertPool("../suites/common/ssl/", nil)
|
pool, errs, nonFatalErrs := NewX509CertPool("../suites/common/ssl/")
|
||||||
assert.NotNil(t, pool)
|
assert.NotNil(t, pool)
|
||||||
require.Len(t, errs, 1)
|
require.Len(t, errs, 1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user