refactor: introduce config key gen (#3206)
This adjusts the validated keys to utilize a generated code section.pull/3208/head
parent
5aa25ec275
commit
dc7ca6f03c
|
@ -0,0 +1,199 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/mail"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewRunGenCmd implements the code generation cobra command.
|
||||||
|
func NewRunGenCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "gen",
|
||||||
|
RunE: runGenE,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runGenE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
if err = genConfigurationKeys(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genConfigurationKeys() (err error) {
|
||||||
|
data := loadKeysTemplate()
|
||||||
|
|
||||||
|
f, err := os.Create("./internal/configuration/schema/keys.go")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return keysTemplate.Execute(f, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
var keysTemplate = template.Must(template.New("keys").Parse(`// Code generated by go generate. DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// Run the following command to generate this file:
|
||||||
|
// go run ./cmd/authelia-scripts gen
|
||||||
|
//
|
||||||
|
|
||||||
|
package schema
|
||||||
|
|
||||||
|
// Keys represents the detected schema keys.
|
||||||
|
var Keys = []string{
|
||||||
|
{{- range .Keys }}
|
||||||
|
{{ printf "%q" . }},
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
|
||||||
|
type keysTemplateStruct struct {
|
||||||
|
Timestamp time.Time
|
||||||
|
Keys []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadKeysTemplate() keysTemplateStruct {
|
||||||
|
config := schema.Configuration{
|
||||||
|
Storage: schema.StorageConfiguration{
|
||||||
|
Local: &schema.LocalStorageConfiguration{},
|
||||||
|
MySQL: &schema.MySQLStorageConfiguration{},
|
||||||
|
PostgreSQL: &schema.PostgreSQLStorageConfiguration{},
|
||||||
|
},
|
||||||
|
Notifier: schema.NotifierConfiguration{
|
||||||
|
FileSystem: &schema.FileSystemNotifierConfiguration{},
|
||||||
|
SMTP: &schema.SMTPNotifierConfiguration{
|
||||||
|
TLS: &schema.TLSConfig{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
AuthenticationBackend: schema.AuthenticationBackendConfiguration{
|
||||||
|
File: &schema.FileAuthenticationBackendConfiguration{
|
||||||
|
Password: &schema.PasswordConfiguration{},
|
||||||
|
},
|
||||||
|
LDAP: &schema.LDAPAuthenticationBackendConfiguration{
|
||||||
|
TLS: &schema.TLSConfig{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Session: schema.SessionConfiguration{
|
||||||
|
Redis: &schema.RedisSessionConfiguration{
|
||||||
|
TLS: &schema.TLSConfig{},
|
||||||
|
HighAvailability: &schema.RedisHighAvailabilityConfiguration{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IdentityProviders: schema.IdentityProvidersConfiguration{
|
||||||
|
OIDC: &schema.OpenIDConnectConfiguration{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return keysTemplateStruct{
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
Keys: readTags("", reflect.TypeOf(config)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var decodedTypes = []reflect.Type{
|
||||||
|
reflect.TypeOf(mail.Address{}),
|
||||||
|
reflect.TypeOf(regexp.Regexp{}),
|
||||||
|
reflect.TypeOf(url.URL{}),
|
||||||
|
reflect.TypeOf(time.Duration(0)),
|
||||||
|
}
|
||||||
|
|
||||||
|
func containsType(needle reflect.Type, haystack []reflect.Type) (contains bool) {
|
||||||
|
for _, t := range haystack {
|
||||||
|
if needle.Kind() == reflect.Ptr {
|
||||||
|
if needle.Elem() == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if needle == t {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTags(prefix string, t reflect.Type) (tags []string) {
|
||||||
|
tags = make([]string, 0)
|
||||||
|
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
|
||||||
|
tag := field.Tag.Get("koanf")
|
||||||
|
|
||||||
|
if tag == "" {
|
||||||
|
tags = append(tags, prefix)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch field.Type.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
if !containsType(field.Type, decodedTypes) {
|
||||||
|
tags = append(tags, readTags(getKeyNameFromTagAndPrefix(prefix, tag, false), field.Type)...)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
if field.Type.Elem().Kind() == reflect.Struct {
|
||||||
|
if !containsType(field.Type.Elem(), decodedTypes) {
|
||||||
|
tags = append(tags, getKeyNameFromTagAndPrefix(prefix, tag, false))
|
||||||
|
tags = append(tags, readTags(getKeyNameFromTagAndPrefix(prefix, tag, true), field.Type.Elem())...)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Ptr:
|
||||||
|
switch field.Type.Elem().Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
if !containsType(field.Type.Elem(), decodedTypes) {
|
||||||
|
tags = append(tags, readTags(getKeyNameFromTagAndPrefix(prefix, tag, false), field.Type.Elem())...)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
if field.Type.Elem().Elem().Kind() == reflect.Struct {
|
||||||
|
if !containsType(field.Type.Elem(), decodedTypes) {
|
||||||
|
tags = append(tags, readTags(getKeyNameFromTagAndPrefix(prefix, tag, true), field.Type.Elem())...)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = append(tags, getKeyNameFromTagAndPrefix(prefix, tag, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKeyNameFromTagAndPrefix(prefix, name string, slice bool) string {
|
||||||
|
nameParts := strings.SplitN(name, ",", 2)
|
||||||
|
|
||||||
|
if prefix == "" {
|
||||||
|
return nameParts[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(nameParts) == 2 && nameParts[1] == "squash" {
|
||||||
|
return prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
if slice {
|
||||||
|
return fmt.Sprintf("%s.%s[]", prefix, nameParts[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s.%s", prefix, nameParts[0])
|
||||||
|
}
|
|
@ -136,7 +136,7 @@ func main() {
|
||||||
cobraCommands = append(cobraCommands, command)
|
cobraCommands = append(cobraCommands, command)
|
||||||
}
|
}
|
||||||
|
|
||||||
cobraCommands = append(cobraCommands, commands.NewHashPasswordCmd(), commands.NewCertificatesCmd(), commands.NewRSACmd(), xflagsCmd)
|
cobraCommands = append(cobraCommands, commands.NewHashPasswordCmd(), commands.NewCertificatesCmd(), commands.NewRSACmd(), NewRunGenCmd(), xflagsCmd)
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVar(&buildkite, "buildkite", false, "Set CI flag for Buildkite")
|
rootCmd.PersistentFlags().BoolVar(&buildkite, "buildkite", false, "Set CI flag for Buildkite")
|
||||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ func koanfEnvironmentCallback(keyMap map[string]string, ignoredKeys []string, pr
|
||||||
formattedKey := strings.TrimPrefix(key, prefix)
|
formattedKey := strings.TrimPrefix(key, prefix)
|
||||||
formattedKey = strings.ReplaceAll(strings.ToLower(formattedKey), delimiter, constDelimiter)
|
formattedKey = strings.ReplaceAll(strings.ToLower(formattedKey), delimiter, constDelimiter)
|
||||||
|
|
||||||
if utils.IsStringInSlice(formattedKey, validator.ValidKeys) {
|
if utils.IsStringInSlice(formattedKey, schema.Keys) {
|
||||||
return formattedKey, value
|
return formattedKey, value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ func koanfCommandLineWithMappingCallback(mapping map[string]string, includeValid
|
||||||
if includeValidKeys {
|
if includeValidKeys {
|
||||||
formattedKey := strings.ReplaceAll(flag.Name, "-", "_")
|
formattedKey := strings.ReplaceAll(flag.Name, "-", "_")
|
||||||
|
|
||||||
if utils.IsStringInSlice(formattedKey, validator.ValidKeys) {
|
if utils.IsStringInSlice(formattedKey, schema.Keys) {
|
||||||
return formattedKey, flag.Value.String()
|
return formattedKey, flag.Value.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
// Code generated by go generate. DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// Run the following command to generate this file:
|
||||||
|
// go run ./cmd/authelia-scripts gen
|
||||||
|
//
|
||||||
|
|
||||||
|
package schema
|
||||||
|
|
||||||
|
// Keys represents the detected schema keys.
|
||||||
|
var Keys = []string{
|
||||||
|
"theme",
|
||||||
|
"certificates_directory",
|
||||||
|
"jwt_secret",
|
||||||
|
"default_redirection_url",
|
||||||
|
"log.level",
|
||||||
|
"log.format",
|
||||||
|
"log.file_path",
|
||||||
|
"log.keep_stdout",
|
||||||
|
"identity_providers.oidc.hmac_secret",
|
||||||
|
"identity_providers.oidc.issuer_private_key",
|
||||||
|
"identity_providers.oidc.access_token_lifespan",
|
||||||
|
"identity_providers.oidc.authorize_code_lifespan",
|
||||||
|
"identity_providers.oidc.id_token_lifespan",
|
||||||
|
"identity_providers.oidc.refresh_token_lifespan",
|
||||||
|
"identity_providers.oidc.enable_client_debug_messages",
|
||||||
|
"identity_providers.oidc.minimum_parameter_entropy",
|
||||||
|
"identity_providers.oidc.enforce_pkce",
|
||||||
|
"identity_providers.oidc.enable_pkce_plain_challenge",
|
||||||
|
"identity_providers.oidc.cors.endpoints",
|
||||||
|
"identity_providers.oidc.cors.allowed_origins",
|
||||||
|
"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris",
|
||||||
|
"identity_providers.oidc.clients",
|
||||||
|
"identity_providers.oidc.clients[].id",
|
||||||
|
"identity_providers.oidc.clients[].description",
|
||||||
|
"identity_providers.oidc.clients[].secret",
|
||||||
|
"identity_providers.oidc.clients[].sector_identifier",
|
||||||
|
"identity_providers.oidc.clients[].public",
|
||||||
|
"identity_providers.oidc.clients[].redirect_uris",
|
||||||
|
"identity_providers.oidc.clients[].audience",
|
||||||
|
"identity_providers.oidc.clients[].scopes",
|
||||||
|
"identity_providers.oidc.clients[].grant_types",
|
||||||
|
"identity_providers.oidc.clients[].response_types",
|
||||||
|
"identity_providers.oidc.clients[].response_modes",
|
||||||
|
"identity_providers.oidc.clients[].userinfo_signing_algorithm",
|
||||||
|
"identity_providers.oidc.clients[].authorization_policy",
|
||||||
|
"identity_providers.oidc.clients[].pre_configured_consent_duration",
|
||||||
|
"authentication_backend.ldap.implementation",
|
||||||
|
"authentication_backend.ldap.url",
|
||||||
|
"authentication_backend.ldap.timeout",
|
||||||
|
"authentication_backend.ldap.start_tls",
|
||||||
|
"authentication_backend.ldap.tls.minimum_version",
|
||||||
|
"authentication_backend.ldap.tls.skip_verify",
|
||||||
|
"authentication_backend.ldap.tls.server_name",
|
||||||
|
"authentication_backend.ldap.base_dn",
|
||||||
|
"authentication_backend.ldap.additional_users_dn",
|
||||||
|
"authentication_backend.ldap.users_filter",
|
||||||
|
"authentication_backend.ldap.additional_groups_dn",
|
||||||
|
"authentication_backend.ldap.groups_filter",
|
||||||
|
"authentication_backend.ldap.group_name_attribute",
|
||||||
|
"authentication_backend.ldap.username_attribute",
|
||||||
|
"authentication_backend.ldap.mail_attribute",
|
||||||
|
"authentication_backend.ldap.display_name_attribute",
|
||||||
|
"authentication_backend.ldap.user",
|
||||||
|
"authentication_backend.ldap.password",
|
||||||
|
"authentication_backend.file.path",
|
||||||
|
"authentication_backend.file.password.iterations",
|
||||||
|
"authentication_backend.file.password.key_length",
|
||||||
|
"authentication_backend.file.password.salt_length",
|
||||||
|
"authentication_backend.file.password.algorithm",
|
||||||
|
"authentication_backend.file.password.memory",
|
||||||
|
"authentication_backend.file.password.parallelism",
|
||||||
|
"authentication_backend.password_reset.custom_url",
|
||||||
|
"authentication_backend.disable_reset_password",
|
||||||
|
"authentication_backend.refresh_interval",
|
||||||
|
"session.name",
|
||||||
|
"session.domain",
|
||||||
|
"session.same_site",
|
||||||
|
"session.secret",
|
||||||
|
"session.expiration",
|
||||||
|
"session.inactivity",
|
||||||
|
"session.remember_me_duration",
|
||||||
|
"session.redis.host",
|
||||||
|
"session.redis.port",
|
||||||
|
"session.redis.username",
|
||||||
|
"session.redis.password",
|
||||||
|
"session.redis.database_index",
|
||||||
|
"session.redis.maximum_active_connections",
|
||||||
|
"session.redis.minimum_idle_connections",
|
||||||
|
"session.redis.tls.minimum_version",
|
||||||
|
"session.redis.tls.skip_verify",
|
||||||
|
"session.redis.tls.server_name",
|
||||||
|
"session.redis.high_availability.sentinel_name",
|
||||||
|
"session.redis.high_availability.sentinel_username",
|
||||||
|
"session.redis.high_availability.sentinel_password",
|
||||||
|
"session.redis.high_availability.nodes",
|
||||||
|
"session.redis.high_availability.nodes[].host",
|
||||||
|
"session.redis.high_availability.nodes[].port",
|
||||||
|
"session.redis.high_availability.route_by_latency",
|
||||||
|
"session.redis.high_availability.route_randomly",
|
||||||
|
"totp.disable",
|
||||||
|
"totp.issuer",
|
||||||
|
"totp.algorithm",
|
||||||
|
"totp.digits",
|
||||||
|
"totp.period",
|
||||||
|
"totp.skew",
|
||||||
|
"totp.secret_size",
|
||||||
|
"duo_api.disable",
|
||||||
|
"duo_api.hostname",
|
||||||
|
"duo_api.integration_key",
|
||||||
|
"duo_api.secret_key",
|
||||||
|
"duo_api.enable_self_enrollment",
|
||||||
|
"access_control.default_policy",
|
||||||
|
"access_control.networks",
|
||||||
|
"access_control.networks[].name",
|
||||||
|
"access_control.networks[].networks",
|
||||||
|
"access_control.rules",
|
||||||
|
"access_control.rules[].domain",
|
||||||
|
"access_control.rules[].domain_regex",
|
||||||
|
"access_control.rules[].policy",
|
||||||
|
"access_control.rules[].subject",
|
||||||
|
"access_control.rules[].networks",
|
||||||
|
"access_control.rules[].resources",
|
||||||
|
"access_control.rules[].methods",
|
||||||
|
"ntp.address",
|
||||||
|
"ntp.version",
|
||||||
|
"ntp.max_desync",
|
||||||
|
"ntp.disable_startup_check",
|
||||||
|
"ntp.disable_failure",
|
||||||
|
"regulation.max_retries",
|
||||||
|
"regulation.find_time",
|
||||||
|
"regulation.ban_time",
|
||||||
|
"storage.local.path",
|
||||||
|
"storage.mysql.host",
|
||||||
|
"storage.mysql.port",
|
||||||
|
"storage.mysql.database",
|
||||||
|
"storage.mysql.username",
|
||||||
|
"storage.mysql.password",
|
||||||
|
"storage.mysql.timeout",
|
||||||
|
"storage.postgres.host",
|
||||||
|
"storage.postgres.port",
|
||||||
|
"storage.postgres.database",
|
||||||
|
"storage.postgres.username",
|
||||||
|
"storage.postgres.password",
|
||||||
|
"storage.postgres.timeout",
|
||||||
|
"storage.postgres.schema",
|
||||||
|
"storage.postgres.ssl.mode",
|
||||||
|
"storage.postgres.ssl.root_certificate",
|
||||||
|
"storage.postgres.ssl.certificate",
|
||||||
|
"storage.postgres.ssl.key",
|
||||||
|
"storage.postgres.sslmode",
|
||||||
|
"storage.encryption_key",
|
||||||
|
"notifier.disable_startup_check",
|
||||||
|
"notifier.filesystem.filename",
|
||||||
|
"notifier.smtp.host",
|
||||||
|
"notifier.smtp.port",
|
||||||
|
"notifier.smtp.timeout",
|
||||||
|
"notifier.smtp.username",
|
||||||
|
"notifier.smtp.password",
|
||||||
|
"notifier.smtp.identifier",
|
||||||
|
"notifier.smtp.sender",
|
||||||
|
"notifier.smtp.subject",
|
||||||
|
"notifier.smtp.startup_check_address",
|
||||||
|
"notifier.smtp.disable_require_tls",
|
||||||
|
"notifier.smtp.disable_html_emails",
|
||||||
|
"notifier.smtp.tls.minimum_version",
|
||||||
|
"notifier.smtp.tls.skip_verify",
|
||||||
|
"notifier.smtp.tls.server_name",
|
||||||
|
"notifier.template_path",
|
||||||
|
"server.host",
|
||||||
|
"server.port",
|
||||||
|
"server.path",
|
||||||
|
"server.asset_path",
|
||||||
|
"server.read_buffer_size",
|
||||||
|
"server.write_buffer_size",
|
||||||
|
"server.enable_pprof",
|
||||||
|
"server.enable_expvars",
|
||||||
|
"server.disable_healthcheck",
|
||||||
|
"server.tls.certificate",
|
||||||
|
"server.tls.key",
|
||||||
|
"server.tls.client_certificates",
|
||||||
|
"server.headers.csp_template",
|
||||||
|
"webauthn.disable",
|
||||||
|
"webauthn.display_name",
|
||||||
|
"webauthn.attestation_conveyance_preference",
|
||||||
|
"webauthn.user_verification",
|
||||||
|
"webauthn.timeout",
|
||||||
|
"password_policy.standard.enabled",
|
||||||
|
"password_policy.standard.min_length",
|
||||||
|
"password_policy.standard.max_length",
|
||||||
|
"password_policy.standard.require_uppercase",
|
||||||
|
"password_policy.standard.require_lowercase",
|
||||||
|
"password_policy.standard.require_number",
|
||||||
|
"password_policy.standard.require_special",
|
||||||
|
"password_policy.zxcvbn.enabled",
|
||||||
|
"password_policy.zxcvbn.min_score",
|
||||||
|
}
|
|
@ -0,0 +1,253 @@
|
||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ValidKeys = []string{
|
||||||
|
// Root Keys.
|
||||||
|
"certificates_directory",
|
||||||
|
"theme",
|
||||||
|
"default_redirection_url",
|
||||||
|
"jwt_secret",
|
||||||
|
|
||||||
|
// Log keys.
|
||||||
|
"log.level",
|
||||||
|
"log.format",
|
||||||
|
"log.file_path",
|
||||||
|
"log.keep_stdout",
|
||||||
|
|
||||||
|
// Server Keys.
|
||||||
|
"server.host",
|
||||||
|
"server.port",
|
||||||
|
"server.read_buffer_size",
|
||||||
|
"server.write_buffer_size",
|
||||||
|
"server.path",
|
||||||
|
"server.asset_path",
|
||||||
|
"server.enable_pprof",
|
||||||
|
"server.enable_expvars",
|
||||||
|
"server.disable_healthcheck",
|
||||||
|
"server.tls.key",
|
||||||
|
"server.tls.certificate",
|
||||||
|
"server.tls.client_certificates",
|
||||||
|
"server.headers.csp_template",
|
||||||
|
|
||||||
|
// TOTP Keys.
|
||||||
|
"totp.disable",
|
||||||
|
"totp.issuer",
|
||||||
|
"totp.algorithm",
|
||||||
|
"totp.digits",
|
||||||
|
"totp.period",
|
||||||
|
"totp.skew",
|
||||||
|
"totp.secret_size",
|
||||||
|
|
||||||
|
// Webauthn Keys.
|
||||||
|
"webauthn.disable",
|
||||||
|
"webauthn.display_name",
|
||||||
|
"webauthn.attestation_conveyance_preference",
|
||||||
|
"webauthn.user_verification",
|
||||||
|
"webauthn.timeout",
|
||||||
|
|
||||||
|
// DUO API Keys.
|
||||||
|
"duo_api.disable",
|
||||||
|
"duo_api.hostname",
|
||||||
|
"duo_api.enable_self_enrollment",
|
||||||
|
"duo_api.secret_key",
|
||||||
|
"duo_api.integration_key",
|
||||||
|
|
||||||
|
// Access Control Keys.
|
||||||
|
"access_control.default_policy",
|
||||||
|
"access_control.networks",
|
||||||
|
"access_control.networks[].name",
|
||||||
|
"access_control.networks[].networks",
|
||||||
|
"access_control.rules",
|
||||||
|
"access_control.rules[].domain",
|
||||||
|
"access_control.rules[].domain_regex",
|
||||||
|
"access_control.rules[].methods",
|
||||||
|
"access_control.rules[].networks",
|
||||||
|
"access_control.rules[].subject",
|
||||||
|
"access_control.rules[].policy",
|
||||||
|
"access_control.rules[].resources",
|
||||||
|
|
||||||
|
// Session Keys.
|
||||||
|
"session.name",
|
||||||
|
"session.domain",
|
||||||
|
"session.secret",
|
||||||
|
"session.same_site",
|
||||||
|
"session.expiration",
|
||||||
|
"session.inactivity",
|
||||||
|
"session.remember_me_duration",
|
||||||
|
|
||||||
|
// Redis Session Keys.
|
||||||
|
"session.redis.host",
|
||||||
|
"session.redis.port",
|
||||||
|
"session.redis.username",
|
||||||
|
"session.redis.password",
|
||||||
|
"session.redis.database_index",
|
||||||
|
"session.redis.maximum_active_connections",
|
||||||
|
"session.redis.minimum_idle_connections",
|
||||||
|
"session.redis.tls.minimum_version",
|
||||||
|
"session.redis.tls.skip_verify",
|
||||||
|
"session.redis.tls.server_name",
|
||||||
|
"session.redis.high_availability.sentinel_name",
|
||||||
|
"session.redis.high_availability.sentinel_username",
|
||||||
|
"session.redis.high_availability.sentinel_password",
|
||||||
|
"session.redis.high_availability.nodes",
|
||||||
|
"session.redis.high_availability.nodes[].host",
|
||||||
|
"session.redis.high_availability.nodes[].port",
|
||||||
|
"session.redis.high_availability.route_by_latency",
|
||||||
|
"session.redis.high_availability.route_randomly",
|
||||||
|
|
||||||
|
// Storage Keys.
|
||||||
|
"storage.encryption_key",
|
||||||
|
|
||||||
|
// Local Storage Keys.
|
||||||
|
"storage.local.path",
|
||||||
|
|
||||||
|
// MySQL Storage Keys.
|
||||||
|
"storage.mysql.host",
|
||||||
|
"storage.mysql.port",
|
||||||
|
"storage.mysql.database",
|
||||||
|
"storage.mysql.username",
|
||||||
|
"storage.mysql.password",
|
||||||
|
"storage.mysql.timeout",
|
||||||
|
|
||||||
|
// PostgreSQL Storage Keys.
|
||||||
|
"storage.postgres.host",
|
||||||
|
"storage.postgres.port",
|
||||||
|
"storage.postgres.database",
|
||||||
|
"storage.postgres.username",
|
||||||
|
"storage.postgres.password",
|
||||||
|
"storage.postgres.timeout",
|
||||||
|
"storage.postgres.schema",
|
||||||
|
"storage.postgres.ssl.mode",
|
||||||
|
"storage.postgres.ssl.root_certificate",
|
||||||
|
"storage.postgres.ssl.certificate",
|
||||||
|
"storage.postgres.ssl.key",
|
||||||
|
|
||||||
|
"storage.postgres.sslmode", // Deprecated. TODO: Remove in v4.36.0.
|
||||||
|
|
||||||
|
// FileSystem Notifier Keys.
|
||||||
|
"notifier.filesystem.filename",
|
||||||
|
"notifier.disable_startup_check",
|
||||||
|
|
||||||
|
// SMTP Notifier Keys.
|
||||||
|
"notifier.smtp.host",
|
||||||
|
"notifier.smtp.port",
|
||||||
|
"notifier.smtp.timeout",
|
||||||
|
"notifier.smtp.username",
|
||||||
|
"notifier.smtp.password",
|
||||||
|
"notifier.smtp.identifier",
|
||||||
|
"notifier.smtp.sender",
|
||||||
|
"notifier.smtp.subject",
|
||||||
|
"notifier.smtp.startup_check_address",
|
||||||
|
"notifier.smtp.disable_require_tls",
|
||||||
|
"notifier.smtp.disable_html_emails",
|
||||||
|
"notifier.smtp.tls.minimum_version",
|
||||||
|
"notifier.smtp.tls.skip_verify",
|
||||||
|
"notifier.smtp.tls.server_name",
|
||||||
|
"notifier.template_path",
|
||||||
|
|
||||||
|
// Regulation Keys.
|
||||||
|
"regulation.max_retries",
|
||||||
|
"regulation.find_time",
|
||||||
|
"regulation.ban_time",
|
||||||
|
|
||||||
|
// Authentication Backend Keys.
|
||||||
|
"authentication_backend.disable_reset_password",
|
||||||
|
"authentication_backend.password_reset.custom_url",
|
||||||
|
"authentication_backend.refresh_interval",
|
||||||
|
|
||||||
|
// LDAP Authentication Backend Keys.
|
||||||
|
"authentication_backend.ldap.implementation",
|
||||||
|
"authentication_backend.ldap.url",
|
||||||
|
"authentication_backend.ldap.timeout",
|
||||||
|
"authentication_backend.ldap.base_dn",
|
||||||
|
"authentication_backend.ldap.username_attribute",
|
||||||
|
"authentication_backend.ldap.additional_users_dn",
|
||||||
|
"authentication_backend.ldap.users_filter",
|
||||||
|
"authentication_backend.ldap.additional_groups_dn",
|
||||||
|
"authentication_backend.ldap.groups_filter",
|
||||||
|
"authentication_backend.ldap.group_name_attribute",
|
||||||
|
"authentication_backend.ldap.mail_attribute",
|
||||||
|
"authentication_backend.ldap.display_name_attribute",
|
||||||
|
"authentication_backend.ldap.user",
|
||||||
|
"authentication_backend.ldap.password",
|
||||||
|
"authentication_backend.ldap.start_tls",
|
||||||
|
"authentication_backend.ldap.tls.minimum_version",
|
||||||
|
"authentication_backend.ldap.tls.skip_verify",
|
||||||
|
"authentication_backend.ldap.tls.server_name",
|
||||||
|
|
||||||
|
// File Authentication Backend Keys.
|
||||||
|
"authentication_backend.file.path",
|
||||||
|
"authentication_backend.file.password.algorithm",
|
||||||
|
"authentication_backend.file.password.iterations",
|
||||||
|
"authentication_backend.file.password.key_length",
|
||||||
|
"authentication_backend.file.password.salt_length",
|
||||||
|
"authentication_backend.file.password.memory",
|
||||||
|
"authentication_backend.file.password.parallelism",
|
||||||
|
|
||||||
|
// Identity Provider Keys.
|
||||||
|
"identity_providers.oidc.hmac_secret",
|
||||||
|
"identity_providers.oidc.issuer_private_key",
|
||||||
|
"identity_providers.oidc.id_token_lifespan",
|
||||||
|
"identity_providers.oidc.access_token_lifespan",
|
||||||
|
"identity_providers.oidc.refresh_token_lifespan",
|
||||||
|
"identity_providers.oidc.authorize_code_lifespan",
|
||||||
|
"identity_providers.oidc.enforce_pkce",
|
||||||
|
"identity_providers.oidc.enable_pkce_plain_challenge",
|
||||||
|
"identity_providers.oidc.enable_client_debug_messages",
|
||||||
|
"identity_providers.oidc.minimum_parameter_entropy",
|
||||||
|
"identity_providers.oidc.cors.endpoints",
|
||||||
|
"identity_providers.oidc.cors.allowed_origins",
|
||||||
|
"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris",
|
||||||
|
"identity_providers.oidc.clients",
|
||||||
|
"identity_providers.oidc.clients[].id",
|
||||||
|
"identity_providers.oidc.clients[].description",
|
||||||
|
"identity_providers.oidc.clients[].secret",
|
||||||
|
"identity_providers.oidc.clients[].sector_identifier",
|
||||||
|
"identity_providers.oidc.clients[].public",
|
||||||
|
"identity_providers.oidc.clients[].redirect_uris",
|
||||||
|
"identity_providers.oidc.clients[].authorization_policy",
|
||||||
|
"identity_providers.oidc.clients[].pre_configured_consent_duration",
|
||||||
|
"identity_providers.oidc.clients[].scopes",
|
||||||
|
"identity_providers.oidc.clients[].audience",
|
||||||
|
"identity_providers.oidc.clients[].grant_types",
|
||||||
|
"identity_providers.oidc.clients[].response_types",
|
||||||
|
"identity_providers.oidc.clients[].response_modes",
|
||||||
|
"identity_providers.oidc.clients[].userinfo_signing_algorithm",
|
||||||
|
|
||||||
|
// NTP keys.
|
||||||
|
"ntp.address",
|
||||||
|
"ntp.version",
|
||||||
|
"ntp.max_desync",
|
||||||
|
"ntp.disable_startup_check",
|
||||||
|
"ntp.disable_failure",
|
||||||
|
|
||||||
|
// Password Policy keys.
|
||||||
|
"password_policy.standard.enabled",
|
||||||
|
"password_policy.standard.min_length",
|
||||||
|
"password_policy.standard.max_length",
|
||||||
|
"password_policy.standard.require_uppercase",
|
||||||
|
"password_policy.standard.require_lowercase",
|
||||||
|
"password_policy.standard.require_number",
|
||||||
|
"password_policy.standard.require_special",
|
||||||
|
"password_policy.zxcvbn.enabled",
|
||||||
|
"password_policy.zxcvbn.min_score",
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOldKeys(t *testing.T) {
|
||||||
|
for _, key := range ValidKeys {
|
||||||
|
assert.Contains(t, Keys, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range Keys {
|
||||||
|
assert.Contains(t, ValidKeys, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDuplicates(t *testing.T) {
|
||||||
|
assert.Equal(t, len(Keys), len(ValidKeys))
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewYAMLFileSource returns a Source configured to load from a specified YAML path. If there is an issue accessing this
|
// NewYAMLFileSource returns a Source configured to load from a specified YAML path. If there is an issue accessing this
|
||||||
|
@ -75,7 +74,7 @@ func (s *EnvironmentSource) Merge(ko *koanf.Koanf, _ *schema.StructValidator) (e
|
||||||
|
|
||||||
// Load the Source into the EnvironmentSource koanf.Koanf.
|
// Load the Source into the EnvironmentSource koanf.Koanf.
|
||||||
func (s *EnvironmentSource) Load(_ *schema.StructValidator) (err error) {
|
func (s *EnvironmentSource) Load(_ *schema.StructValidator) (err error) {
|
||||||
keyMap, ignoredKeys := getEnvConfigMap(validator.ValidKeys, s.prefix, s.delimiter)
|
keyMap, ignoredKeys := getEnvConfigMap(schema.Keys, s.prefix, s.delimiter)
|
||||||
|
|
||||||
return s.koanf.Load(env.ProviderWithValue(s.prefix, constDelimiter, koanfEnvironmentCallback(keyMap, ignoredKeys, s.prefix, s.delimiter)), nil)
|
return s.koanf.Load(env.ProviderWithValue(s.prefix, constDelimiter, koanfEnvironmentCallback(keyMap, ignoredKeys, s.prefix, s.delimiter)), nil)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +108,7 @@ func (s *SecretsSource) Merge(ko *koanf.Koanf, val *schema.StructValidator) (err
|
||||||
|
|
||||||
// Load the Source into the SecretsSource koanf.Koanf.
|
// Load the Source into the SecretsSource koanf.Koanf.
|
||||||
func (s *SecretsSource) Load(val *schema.StructValidator) (err error) {
|
func (s *SecretsSource) Load(val *schema.StructValidator) (err error) {
|
||||||
keyMap := getSecretConfigMap(validator.ValidKeys, s.prefix, s.delimiter)
|
keyMap := getSecretConfigMap(schema.Keys, s.prefix, s.delimiter)
|
||||||
|
|
||||||
return s.koanf.Load(env.ProviderWithValue(s.prefix, constDelimiter, koanfEnvironmentSecretsCallback(keyMap, val)), nil)
|
return s.koanf.Load(env.ProviderWithValue(s.prefix, constDelimiter, koanfEnvironmentSecretsCallback(keyMap, val)), nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,240 +300,6 @@ var validOIDCCORSEndpoints = []string{oidc.AuthorizationEndpoint, oidc.TokenEndp
|
||||||
|
|
||||||
var reKeyReplacer = regexp.MustCompile(`\[\d+]`)
|
var reKeyReplacer = regexp.MustCompile(`\[\d+]`)
|
||||||
|
|
||||||
// ValidKeys is a list of valid keys that are not secret names. For the sake of consistency please place any secret in
|
|
||||||
// the secret names map and reuse it in relevant sections.
|
|
||||||
var ValidKeys = []string{
|
|
||||||
// Root Keys.
|
|
||||||
"certificates_directory",
|
|
||||||
"theme",
|
|
||||||
"default_redirection_url",
|
|
||||||
"jwt_secret",
|
|
||||||
|
|
||||||
// Log keys.
|
|
||||||
"log.level",
|
|
||||||
"log.format",
|
|
||||||
"log.file_path",
|
|
||||||
"log.keep_stdout",
|
|
||||||
|
|
||||||
// Server Keys.
|
|
||||||
"server.host",
|
|
||||||
"server.port",
|
|
||||||
"server.read_buffer_size",
|
|
||||||
"server.write_buffer_size",
|
|
||||||
"server.path",
|
|
||||||
"server.asset_path",
|
|
||||||
"server.enable_pprof",
|
|
||||||
"server.enable_expvars",
|
|
||||||
"server.disable_healthcheck",
|
|
||||||
"server.tls.key",
|
|
||||||
"server.tls.certificate",
|
|
||||||
"server.tls.client_certificates",
|
|
||||||
"server.headers.csp_template",
|
|
||||||
|
|
||||||
// TOTP Keys.
|
|
||||||
"totp.disable",
|
|
||||||
"totp.issuer",
|
|
||||||
"totp.algorithm",
|
|
||||||
"totp.digits",
|
|
||||||
"totp.period",
|
|
||||||
"totp.skew",
|
|
||||||
"totp.secret_size",
|
|
||||||
|
|
||||||
// Webauthn Keys.
|
|
||||||
"webauthn.disable",
|
|
||||||
"webauthn.display_name",
|
|
||||||
"webauthn.attestation_conveyance_preference",
|
|
||||||
"webauthn.user_verification",
|
|
||||||
"webauthn.timeout",
|
|
||||||
|
|
||||||
// DUO API Keys.
|
|
||||||
"duo_api.disable",
|
|
||||||
"duo_api.hostname",
|
|
||||||
"duo_api.enable_self_enrollment",
|
|
||||||
"duo_api.secret_key",
|
|
||||||
"duo_api.integration_key",
|
|
||||||
|
|
||||||
// Access Control Keys.
|
|
||||||
"access_control.default_policy",
|
|
||||||
"access_control.networks",
|
|
||||||
"access_control.networks[].name",
|
|
||||||
"access_control.networks[].networks",
|
|
||||||
"access_control.rules",
|
|
||||||
"access_control.rules[].domain",
|
|
||||||
"access_control.rules[].domain_regex",
|
|
||||||
"access_control.rules[].methods",
|
|
||||||
"access_control.rules[].networks",
|
|
||||||
"access_control.rules[].subject",
|
|
||||||
"access_control.rules[].policy",
|
|
||||||
"access_control.rules[].resources",
|
|
||||||
|
|
||||||
// Session Keys.
|
|
||||||
"session.name",
|
|
||||||
"session.domain",
|
|
||||||
"session.secret",
|
|
||||||
"session.same_site",
|
|
||||||
"session.expiration",
|
|
||||||
"session.inactivity",
|
|
||||||
"session.remember_me_duration",
|
|
||||||
|
|
||||||
// Redis Session Keys.
|
|
||||||
"session.redis.host",
|
|
||||||
"session.redis.port",
|
|
||||||
"session.redis.username",
|
|
||||||
"session.redis.password",
|
|
||||||
"session.redis.database_index",
|
|
||||||
"session.redis.maximum_active_connections",
|
|
||||||
"session.redis.minimum_idle_connections",
|
|
||||||
"session.redis.tls.minimum_version",
|
|
||||||
"session.redis.tls.skip_verify",
|
|
||||||
"session.redis.tls.server_name",
|
|
||||||
"session.redis.high_availability.sentinel_name",
|
|
||||||
"session.redis.high_availability.sentinel_username",
|
|
||||||
"session.redis.high_availability.sentinel_password",
|
|
||||||
"session.redis.high_availability.nodes",
|
|
||||||
"session.redis.high_availability.nodes[].host",
|
|
||||||
"session.redis.high_availability.nodes[].port",
|
|
||||||
"session.redis.high_availability.route_by_latency",
|
|
||||||
"session.redis.high_availability.route_randomly",
|
|
||||||
|
|
||||||
// Storage Keys.
|
|
||||||
"storage.encryption_key",
|
|
||||||
|
|
||||||
// Local Storage Keys.
|
|
||||||
"storage.local.path",
|
|
||||||
|
|
||||||
// MySQL Storage Keys.
|
|
||||||
"storage.mysql.host",
|
|
||||||
"storage.mysql.port",
|
|
||||||
"storage.mysql.database",
|
|
||||||
"storage.mysql.username",
|
|
||||||
"storage.mysql.password",
|
|
||||||
"storage.mysql.timeout",
|
|
||||||
|
|
||||||
// PostgreSQL Storage Keys.
|
|
||||||
"storage.postgres.host",
|
|
||||||
"storage.postgres.port",
|
|
||||||
"storage.postgres.database",
|
|
||||||
"storage.postgres.username",
|
|
||||||
"storage.postgres.password",
|
|
||||||
"storage.postgres.timeout",
|
|
||||||
"storage.postgres.schema",
|
|
||||||
"storage.postgres.ssl.mode",
|
|
||||||
"storage.postgres.ssl.root_certificate",
|
|
||||||
"storage.postgres.ssl.certificate",
|
|
||||||
"storage.postgres.ssl.key",
|
|
||||||
|
|
||||||
"storage.postgres.sslmode", // Deprecated. TODO: Remove in v4.36.0.
|
|
||||||
|
|
||||||
// FileSystem Notifier Keys.
|
|
||||||
"notifier.filesystem.filename",
|
|
||||||
"notifier.disable_startup_check",
|
|
||||||
|
|
||||||
// SMTP Notifier Keys.
|
|
||||||
"notifier.smtp.host",
|
|
||||||
"notifier.smtp.port",
|
|
||||||
"notifier.smtp.timeout",
|
|
||||||
"notifier.smtp.username",
|
|
||||||
"notifier.smtp.password",
|
|
||||||
"notifier.smtp.identifier",
|
|
||||||
"notifier.smtp.sender",
|
|
||||||
"notifier.smtp.subject",
|
|
||||||
"notifier.smtp.startup_check_address",
|
|
||||||
"notifier.smtp.disable_require_tls",
|
|
||||||
"notifier.smtp.disable_html_emails",
|
|
||||||
"notifier.smtp.tls.minimum_version",
|
|
||||||
"notifier.smtp.tls.skip_verify",
|
|
||||||
"notifier.smtp.tls.server_name",
|
|
||||||
"notifier.template_path",
|
|
||||||
|
|
||||||
// Regulation Keys.
|
|
||||||
"regulation.max_retries",
|
|
||||||
"regulation.find_time",
|
|
||||||
"regulation.ban_time",
|
|
||||||
|
|
||||||
// Authentication Backend Keys.
|
|
||||||
"authentication_backend.disable_reset_password",
|
|
||||||
"authentication_backend.password_reset.custom_url",
|
|
||||||
"authentication_backend.refresh_interval",
|
|
||||||
|
|
||||||
// LDAP Authentication Backend Keys.
|
|
||||||
"authentication_backend.ldap.implementation",
|
|
||||||
"authentication_backend.ldap.url",
|
|
||||||
"authentication_backend.ldap.timeout",
|
|
||||||
"authentication_backend.ldap.base_dn",
|
|
||||||
"authentication_backend.ldap.username_attribute",
|
|
||||||
"authentication_backend.ldap.additional_users_dn",
|
|
||||||
"authentication_backend.ldap.users_filter",
|
|
||||||
"authentication_backend.ldap.additional_groups_dn",
|
|
||||||
"authentication_backend.ldap.groups_filter",
|
|
||||||
"authentication_backend.ldap.group_name_attribute",
|
|
||||||
"authentication_backend.ldap.mail_attribute",
|
|
||||||
"authentication_backend.ldap.display_name_attribute",
|
|
||||||
"authentication_backend.ldap.user",
|
|
||||||
"authentication_backend.ldap.password",
|
|
||||||
"authentication_backend.ldap.start_tls",
|
|
||||||
"authentication_backend.ldap.tls.minimum_version",
|
|
||||||
"authentication_backend.ldap.tls.skip_verify",
|
|
||||||
"authentication_backend.ldap.tls.server_name",
|
|
||||||
|
|
||||||
// File Authentication Backend Keys.
|
|
||||||
"authentication_backend.file.path",
|
|
||||||
"authentication_backend.file.password.algorithm",
|
|
||||||
"authentication_backend.file.password.iterations",
|
|
||||||
"authentication_backend.file.password.key_length",
|
|
||||||
"authentication_backend.file.password.salt_length",
|
|
||||||
"authentication_backend.file.password.memory",
|
|
||||||
"authentication_backend.file.password.parallelism",
|
|
||||||
|
|
||||||
// Identity Provider Keys.
|
|
||||||
"identity_providers.oidc.hmac_secret",
|
|
||||||
"identity_providers.oidc.issuer_private_key",
|
|
||||||
"identity_providers.oidc.id_token_lifespan",
|
|
||||||
"identity_providers.oidc.access_token_lifespan",
|
|
||||||
"identity_providers.oidc.refresh_token_lifespan",
|
|
||||||
"identity_providers.oidc.authorize_code_lifespan",
|
|
||||||
"identity_providers.oidc.enforce_pkce",
|
|
||||||
"identity_providers.oidc.enable_pkce_plain_challenge",
|
|
||||||
"identity_providers.oidc.enable_client_debug_messages",
|
|
||||||
"identity_providers.oidc.minimum_parameter_entropy",
|
|
||||||
"identity_providers.oidc.cors.endpoints",
|
|
||||||
"identity_providers.oidc.cors.allowed_origins",
|
|
||||||
"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris",
|
|
||||||
"identity_providers.oidc.clients",
|
|
||||||
"identity_providers.oidc.clients[].id",
|
|
||||||
"identity_providers.oidc.clients[].description",
|
|
||||||
"identity_providers.oidc.clients[].secret",
|
|
||||||
"identity_providers.oidc.clients[].sector_identifier",
|
|
||||||
"identity_providers.oidc.clients[].public",
|
|
||||||
"identity_providers.oidc.clients[].redirect_uris",
|
|
||||||
"identity_providers.oidc.clients[].authorization_policy",
|
|
||||||
"identity_providers.oidc.clients[].pre_configured_consent_duration",
|
|
||||||
"identity_providers.oidc.clients[].scopes",
|
|
||||||
"identity_providers.oidc.clients[].audience",
|
|
||||||
"identity_providers.oidc.clients[].grant_types",
|
|
||||||
"identity_providers.oidc.clients[].response_types",
|
|
||||||
"identity_providers.oidc.clients[].response_modes",
|
|
||||||
"identity_providers.oidc.clients[].userinfo_signing_algorithm",
|
|
||||||
|
|
||||||
// NTP keys.
|
|
||||||
"ntp.address",
|
|
||||||
"ntp.version",
|
|
||||||
"ntp.max_desync",
|
|
||||||
"ntp.disable_startup_check",
|
|
||||||
"ntp.disable_failure",
|
|
||||||
|
|
||||||
// Password Policy keys.
|
|
||||||
"password_policy.standard.enabled",
|
|
||||||
"password_policy.standard.min_length",
|
|
||||||
"password_policy.standard.max_length",
|
|
||||||
"password_policy.standard.require_uppercase",
|
|
||||||
"password_policy.standard.require_lowercase",
|
|
||||||
"password_policy.standard.require_number",
|
|
||||||
"password_policy.standard.require_special",
|
|
||||||
"password_policy.zxcvbn.enabled",
|
|
||||||
"password_policy.zxcvbn.min_score",
|
|
||||||
}
|
|
||||||
|
|
||||||
var replacedKeys = map[string]string{
|
var replacedKeys = map[string]string{
|
||||||
"authentication_backend.ldap.skip_verify": "authentication_backend.ldap.tls.skip_verify",
|
"authentication_backend.ldap.skip_verify": "authentication_backend.ldap.tls.skip_verify",
|
||||||
"authentication_backend.ldap.minimum_tls_version": "authentication_backend.ldap.tls.minimum_version",
|
"authentication_backend.ldap.minimum_tls_version": "authentication_backend.ldap.tls.minimum_version",
|
||||||
|
|
|
@ -16,7 +16,7 @@ func ValidateKeys(keys []string, prefix string, validator *schema.StructValidato
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
expectedKey := reKeyReplacer.ReplaceAllString(key, "[]")
|
expectedKey := reKeyReplacer.ReplaceAllString(key, "[]")
|
||||||
|
|
||||||
if utils.IsStringInSlice(expectedKey, ValidKeys) {
|
if utils.IsStringInSlice(expectedKey, schema.Keys) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldValidateGoodKeys(t *testing.T) {
|
func TestShouldValidateGoodKeys(t *testing.T) {
|
||||||
configKeys := ValidKeys
|
configKeys := schema.Keys
|
||||||
val := schema.NewStructValidator()
|
val := schema.NewStructValidator()
|
||||||
ValidateKeys(configKeys, "AUTHELIA_", val)
|
ValidateKeys(configKeys, "AUTHELIA_", val)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ func TestShouldValidateGoodKeys(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldNotValidateBadKeys(t *testing.T) {
|
func TestShouldNotValidateBadKeys(t *testing.T) {
|
||||||
configKeys := ValidKeys
|
configKeys := schema.Keys
|
||||||
configKeys = append(configKeys, "bad_key")
|
configKeys = append(configKeys, "bad_key")
|
||||||
configKeys = append(configKeys, "totp.skewy")
|
configKeys = append(configKeys, "totp.skewy")
|
||||||
val := schema.NewStructValidator()
|
val := schema.NewStructValidator()
|
||||||
|
@ -34,7 +34,7 @@ func TestShouldNotValidateBadKeys(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldNotValidateBadEnvKeys(t *testing.T) {
|
func TestShouldNotValidateBadEnvKeys(t *testing.T) {
|
||||||
configKeys := ValidKeys
|
configKeys := schema.Keys
|
||||||
configKeys = append(configKeys, "AUTHELIA__BAD_ENV_KEY")
|
configKeys = append(configKeys, "AUTHELIA__BAD_ENV_KEY")
|
||||||
configKeys = append(configKeys, "AUTHELIA_BAD_ENV_KEY")
|
configKeys = append(configKeys, "AUTHELIA_BAD_ENV_KEY")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue