feat(configuration): freeipa ldap implementation (#4482)

This adds a FreeIPA LDAP implementation which purely adds sane defaults for FreeIPA. There are no functional differences just when the implementation option is set to 'freeipa' sane defaults which should be sufficient for most use cases are set. See the documentation at https://www.authelia.com/r/ldap#defaults for more details.

Closes #2177, Closes #2161
pull/4483/head^2
James Elliott 2022-12-21 21:07:00 +11:00 committed by GitHub
parent c7f4d5999d
commit d0d80b4f66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 166 additions and 50 deletions

View File

@ -284,8 +284,9 @@ authentication_backend:
# ldap: # ldap:
## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
## Acceptable options are as follows: ## Acceptable options are as follows:
## - 'activedirectory' - For Microsoft Active Directory. ## - 'activedirectory' - for Microsoft Active Directory.
## - 'custom' - For custom specifications of attributes and filters. ## - 'freeipa' - for FreeIPA.
## - 'custom' - for custom specifications of attributes and filters.
## This currently defaults to 'custom' to maintain existing behaviour. ## This currently defaults to 'custom' to maintain existing behaviour.
## ##
## Depending on the option here certain other values in this section have a default value, notably all of the ## Depending on the option here certain other values in this section have a default value, notably all of the

View File

@ -10,6 +10,8 @@ menu:
parent: "guides" parent: "guides"
weight: 220 weight: 220
toc: true toc: true
aliases:
- /r/ldap
--- ---
## Binding ## Binding
@ -46,10 +48,10 @@ Authelia primarily supports this method.
## Implementation Guide ## Implementation Guide
There are currently two implementations, `custom` and `activedirectory`. The `activedirectory` implementation There are currently two implementations, `custom`, `activedirectory`, and `freeipa`. The `activedirectory`
must be used if you wish to allow users to change or reset their password as Active Directory implementation must be used if you wish to allow users to change or reset their password as Active Directory
uses a custom attribute for this, and an input format other implementations do not use. The long term uses a custom attribute and mechanism for this. The long term intention of this is to have logical defaults for various
intention of this is to have logical defaults for various RFC implementations of LDAP. RFC implementations of LDAP.
### Filter replacements ### Filter replacements
@ -86,6 +88,7 @@ Username column.
|:---------------:|:--------------:|:------------:|:----:|:----------:| |:---------------:|:--------------:|:------------:|:----:|:----------:|
| custom | N/A | displayName | mail | cn | | custom | N/A | displayName | mail | cn |
| activedirectory | sAMAccountName | displayName | mail | cn | | activedirectory | sAMAccountName | displayName | mail | cn |
| freeipa | uid | displayName | mail | cn |
#### Filter defaults #### Filter defaults
@ -98,6 +101,7 @@ value is not 0 which means the password requires changing at the next login.
|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:| |:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:|
| custom | N/A | N/A | | custom | N/A | N/A |
| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) | | activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) |
| freeipa | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))) | (&(member={dn})(objectClass=groupOfNames)) |
##### Microsoft Active Directory sAMAccountType ##### Microsoft Active Directory sAMAccountType

View File

@ -284,8 +284,9 @@ authentication_backend:
# ldap: # ldap:
## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
## Acceptable options are as follows: ## Acceptable options are as follows:
## - 'activedirectory' - For Microsoft Active Directory. ## - 'activedirectory' - for Microsoft Active Directory.
## - 'custom' - For custom specifications of attributes and filters. ## - 'freeipa' - for FreeIPA.
## - 'custom' - for custom specifications of attributes and filters.
## This currently defaults to 'custom' to maintain existing behaviour. ## This currently defaults to 'custom' to maintain existing behaviour.
## ##
## Depending on the option here certain other values in this section have a default value, notably all of the ## Depending on the option here certain other values in this section have a default value, notably all of the

View File

@ -175,24 +175,38 @@ var DefaultCIPasswordConfig = Password{
// DefaultLDAPAuthenticationBackendConfigurationImplementationCustom represents the default LDAP config. // DefaultLDAPAuthenticationBackendConfigurationImplementationCustom represents the default LDAP config.
var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuthenticationBackend{ var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuthenticationBackend{
UsernameAttribute: "uid", UsernameAttribute: ldapAttrUserID,
MailAttribute: "mail", MailAttribute: ldapAttrMail,
DisplayNameAttribute: "displayName", DisplayNameAttribute: ldapAttrDisplayName,
GroupNameAttribute: "cn", GroupNameAttribute: ldapAttrCommonName,
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLSConfig{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory represents the default LDAP config for the MSAD Implementation. // DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory represents the default LDAP config for the LDAPImplementationActiveDirectory Implementation.
var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = LDAPAuthenticationBackend{ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = LDAPAuthenticationBackend{
UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0)))", UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0)))",
UsernameAttribute: "sAMAccountName", UsernameAttribute: "sAMAccountName",
MailAttribute: "mail", MailAttribute: ldapAttrMail,
DisplayNameAttribute: "displayName", DisplayNameAttribute: ldapAttrDisplayName,
GroupsFilter: "(&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912)))", GroupsFilter: "(&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912)))",
GroupNameAttribute: "cn", GroupNameAttribute: ldapAttrCommonName,
Timeout: time.Second * 5,
TLS: &TLSConfig{
MinimumVersion: TLSVersion{tls.VersionTLS12},
},
}
// DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA represents the default LDAP config for the LDAPImplementationFreeIPA Implementation.
var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAuthenticationBackend{
UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE)))",
UsernameAttribute: ldapAttrUserID,
MailAttribute: ldapAttrMail,
DisplayNameAttribute: ldapAttrDisplayName,
GroupsFilter: "(&(member={dn})(objectClass=groupOfNames))",
GroupNameAttribute: ldapAttrCommonName,
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLSConfig{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},

View File

@ -64,6 +64,9 @@ const (
// LDAPImplementationActiveDirectory is the string for the Active Directory LDAP implementation. // LDAPImplementationActiveDirectory is the string for the Active Directory LDAP implementation.
LDAPImplementationActiveDirectory = "activedirectory" LDAPImplementationActiveDirectory = "activedirectory"
// LDAPImplementationFreeIPA is the string for the FreeIPA LDAP implementation.
LDAPImplementationFreeIPA = "freeipa"
) )
// TOTP Algorithm. // TOTP Algorithm.
@ -99,3 +102,10 @@ const (
blockCERTIFICATE = "CERTIFICATE" blockCERTIFICATE = "CERTIFICATE"
blockRSAPRIVATEKEY = "RSA PRIVATE KEY" blockRSAPRIVATEKEY = "RSA PRIVATE KEY"
) )
const (
ldapAttrMail = "mail"
ldapAttrUserID = "uid"
ldapAttrDisplayName = "displayName"
ldapAttrCommonName = "cn"
)

View File

@ -328,8 +328,10 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val
implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom
case schema.LDAPImplementationActiveDirectory: case schema.LDAPImplementationActiveDirectory:
implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory
case schema.LDAPImplementationFreeIPA:
implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA
default: default:
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendImplementation, config.LDAP.Implementation, strings.Join([]string{schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory}, "', '"))) validator.Push(fmt.Errorf(errFmtLDAPAuthBackendImplementation, config.LDAP.Implementation, strings.Join(validLDAPImplementations, "', '")))
} }
configDefaultTLS := &schema.TLSConfig{} configDefaultTLS := &schema.TLSConfig{}

View File

@ -609,7 +609,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenImplementat
suite.Assert().Len(suite.validator.Warnings(), 0) suite.Assert().Len(suite.validator.Warnings(), 0)
suite.Require().Len(suite.validator.Errors(), 1) suite.Require().Len(suite.validator.Errors(), 1)
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'implementation' is configured as 'masd' but must be one of the following values: 'custom', 'activedirectory'") suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'implementation' is configured as 'masd' but must be one of the following values: 'custom', 'activedirectory', 'freeipa'")
} }
func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvided() { func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvided() {
@ -875,7 +875,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowTLSVerMinGreaterT
suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.2") suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.2")
} }
func TestLdapAuthenticationBackend(t *testing.T) { func TestLDAPAuthenticationBackend(t *testing.T) {
suite.Run(t, new(LDAPAuthenticationBackendSuite)) suite.Run(t, new(LDAPAuthenticationBackendSuite))
} }
@ -894,7 +894,7 @@ func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() {
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
suite.config.LDAP.Password = testLDAPPassword suite.config.LDAP.Password = testLDAPPassword
suite.config.LDAP.BaseDN = testLDAPBaseDN suite.config.LDAP.BaseDN = testLDAPBaseDN
suite.config.LDAP.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS suite.config.LDAP.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.TLS
} }
func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirectoryDefaults() { func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirectoryDefaults() {
@ -904,7 +904,7 @@ func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldSetActiveDirec
suite.Assert().Len(suite.validator.Errors(), 0) suite.Assert().Len(suite.validator.Errors(), 0)
suite.Assert().Equal( suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.Timeout, schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.Timeout,
suite.config.LDAP.Timeout) suite.config.LDAP.Timeout)
suite.Assert().Equal( suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.UsersFilter, schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.UsersFilter,
@ -938,7 +938,7 @@ func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldOnlySetDefault
ValidateAuthenticationBackend(&suite.config, suite.validator) ValidateAuthenticationBackend(&suite.config, suite.validator)
suite.Assert().NotEqual( suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.Timeout, schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.Timeout,
suite.config.LDAP.Timeout) suite.config.LDAP.Timeout)
suite.Assert().NotEqual( suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.UsersFilter, schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory.UsersFilter,
@ -981,3 +981,88 @@ func (suite *ActiveDirectoryAuthenticationBackendSuite) TestShouldRaiseErrorOnIn
func TestActiveDirectoryAuthenticationBackend(t *testing.T) { func TestActiveDirectoryAuthenticationBackend(t *testing.T) {
suite.Run(t, new(ActiveDirectoryAuthenticationBackendSuite)) suite.Run(t, new(ActiveDirectoryAuthenticationBackendSuite))
} }
type FreeIPAAuthenticationBackendSuite struct {
suite.Suite
config schema.AuthenticationBackend
validator *schema.StructValidator
}
func (suite *FreeIPAAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{}
suite.config.LDAP.Implementation = schema.LDAPImplementationFreeIPA
suite.config.LDAP.URL = testLDAPURL
suite.config.LDAP.User = testLDAPUser
suite.config.LDAP.Password = testLDAPPassword
suite.config.LDAP.BaseDN = testLDAPBaseDN
suite.config.LDAP.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.TLS
}
func (suite *FreeIPAAuthenticationBackendSuite) TestShouldSetDefaults() {
ValidateAuthenticationBackend(&suite.config, suite.validator)
suite.Assert().Len(suite.validator.Warnings(), 0)
suite.Assert().Len(suite.validator.Errors(), 0)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.Timeout,
suite.config.LDAP.Timeout)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.UsersFilter,
suite.config.LDAP.UsersFilter)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.UsernameAttribute,
suite.config.LDAP.UsernameAttribute)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.DisplayNameAttribute,
suite.config.LDAP.DisplayNameAttribute)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.MailAttribute,
suite.config.LDAP.MailAttribute)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.GroupsFilter,
suite.config.LDAP.GroupsFilter)
suite.Assert().Equal(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.GroupNameAttribute,
suite.config.LDAP.GroupNameAttribute)
}
func (suite *FreeIPAAuthenticationBackendSuite) TestShouldOnlySetDefaultsIfNotManuallyConfigured() {
suite.config.LDAP.Timeout = time.Second * 2
suite.config.LDAP.UsersFilter = "(&({username_attribute}={input})(objectClass=person)(!(nsAccountLock=TRUE)))"
suite.config.LDAP.UsernameAttribute = "dn"
suite.config.LDAP.MailAttribute = "email"
suite.config.LDAP.DisplayNameAttribute = "gecos"
suite.config.LDAP.GroupsFilter = "(&(member={dn})(objectClass=posixgroup))"
suite.config.LDAP.GroupNameAttribute = "groupName"
ValidateAuthenticationBackend(&suite.config, suite.validator)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.Timeout,
suite.config.LDAP.Timeout)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.UsersFilter,
suite.config.LDAP.UsersFilter)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.UsernameAttribute,
suite.config.LDAP.UsernameAttribute)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.DisplayNameAttribute,
suite.config.LDAP.DisplayNameAttribute)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.MailAttribute,
suite.config.LDAP.MailAttribute)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.GroupsFilter,
suite.config.LDAP.GroupsFilter)
suite.Assert().NotEqual(
schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA.GroupNameAttribute,
suite.config.LDAP.GroupNameAttribute)
}
func TestFreeIPAAuthenticationBackend(t *testing.T) {
suite.Run(t, new(FreeIPAAuthenticationBackendSuite))
}

View File

@ -5,6 +5,8 @@ import (
"github.com/go-webauthn/webauthn/protocol" "github.com/go-webauthn/webauthn/protocol"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/oidc" "github.com/authelia/authelia/v4/internal/oidc"
) )
@ -311,32 +313,6 @@ const (
errFilePOptions = "config key incorrect: authentication_backend.file.password_options should be authentication_backend.file.password" errFilePOptions = "config key incorrect: authentication_backend.file.password_options should be authentication_backend.file.password"
) )
var validArgon2Variants = []string{"argon2id", "id", "argon2i", "i", "argon2d", "d"}
var validSHA2CryptVariants = []string{digestSHA256, digestSHA512}
var validPBKDF2Variants = []string{digestSHA1, digestSHA224, digestSHA256, digestSHA384, digestSHA512}
var validBCryptVariants = []string{"standard", digestSHA256}
var validHashAlgorithms = []string{hashSHA2Crypt, hashPBKDF2, hashSCrypt, hashBCrypt, hashArgon2}
var validStoragePostgreSQLSSLModes = []string{"disable", "require", "verify-ca", "verify-full"}
var validThemeNames = []string{"light", "dark", "grey", "auto"}
var validSessionSameSiteValues = []string{"none", "lax", "strict"}
var validLoLevels = []string{"trace", "debug", "info", "warn", "error"}
var validWebauthnConveyancePreferences = []string{string(protocol.PreferNoAttestation), string(protocol.PreferIndirectAttestation), string(protocol.PreferDirectAttestation)}
var validWebauthnUserVerificationRequirement = []string{string(protocol.VerificationDiscouraged), string(protocol.VerificationPreferred), string(protocol.VerificationRequired)}
var validRFC7231HTTPMethodVerbs = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"}
var validRFC4918HTTPMethodVerbs = []string{"COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK"}
const ( const (
operatorPresent = "present" operatorPresent = "present"
operatorAbsent = "absent" operatorAbsent = "absent"
@ -346,6 +322,29 @@ const (
operatorNotPattern = "not pattern" operatorNotPattern = "not pattern"
) )
var (
validLDAPImplementations = []string{schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory, schema.LDAPImplementationFreeIPA}
)
var (
validArgon2Variants = []string{"argon2id", "id", "argon2i", "i", "argon2d", "d"}
validSHA2CryptVariants = []string{digestSHA256, digestSHA512}
validPBKDF2Variants = []string{digestSHA1, digestSHA224, digestSHA256, digestSHA384, digestSHA512}
validBCryptVariants = []string{"standard", digestSHA256}
validHashAlgorithms = []string{hashSHA2Crypt, hashPBKDF2, hashSCrypt, hashBCrypt, hashArgon2}
)
var (
validStoragePostgreSQLSSLModes = []string{"disable", "require", "verify-ca", "verify-full"}
validThemeNames = []string{"light", "dark", "grey", "auto"}
validSessionSameSiteValues = []string{"none", "lax", "strict"}
validLogLevels = []string{"trace", "debug", "info", "warn", "error"}
validWebauthnConveyancePreferences = []string{string(protocol.PreferNoAttestation), string(protocol.PreferIndirectAttestation), string(protocol.PreferDirectAttestation)}
validWebauthnUserVerificationRequirement = []string{string(protocol.VerificationDiscouraged), string(protocol.VerificationPreferred), string(protocol.VerificationRequired)}
validRFC7231HTTPMethodVerbs = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"}
validRFC4918HTTPMethodVerbs = []string{"COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK"}
)
var ( var (
validACLHTTPMethodVerbs = append(validRFC7231HTTPMethodVerbs, validRFC4918HTTPMethodVerbs...) validACLHTTPMethodVerbs = append(validRFC7231HTTPMethodVerbs, validRFC4918HTTPMethodVerbs...)
validACLRulePolicies = []string{policyBypass, policyOneFactor, policyTwoFactor, policyDeny} validACLRulePolicies = []string{policyBypass, policyOneFactor, policyTwoFactor, policyDeny}

View File

@ -18,7 +18,7 @@ func ValidateLog(config *schema.Configuration, validator *schema.StructValidator
config.Log.Format = schema.DefaultLoggingConfiguration.Format config.Log.Format = schema.DefaultLoggingConfiguration.Format
} }
if !utils.IsStringInSlice(config.Log.Level, validLoLevels) { if !utils.IsStringInSlice(config.Log.Level, validLogLevels) {
validator.Push(fmt.Errorf(errFmtLoggingLevelInvalid, strings.Join(validLoLevels, "', '"), config.Log.Level)) validator.Push(fmt.Errorf(errFmtLoggingLevelInvalid, strings.Join(validLogLevels, "', '"), config.Log.Level))
} }
} }