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, 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().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
||||
"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.ReplaceAll(strings.ToLower(formattedKey), delimiter, constDelimiter)
|
||||
|
||||
if utils.IsStringInSlice(formattedKey, validator.ValidKeys) {
|
||||
if utils.IsStringInSlice(formattedKey, schema.Keys) {
|
||||
return formattedKey, value
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,7 @@ func koanfCommandLineWithMappingCallback(mapping map[string]string, includeValid
|
|||
if includeValidKeys {
|
||||
formattedKey := strings.ReplaceAll(flag.Name, "-", "_")
|
||||
|
||||
if utils.IsStringInSlice(formattedKey, validator.ValidKeys) {
|
||||
if utils.IsStringInSlice(formattedKey, schema.Keys) {
|
||||
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/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
|
||||
|
@ -75,7 +74,7 @@ func (s *EnvironmentSource) Merge(ko *koanf.Koanf, _ *schema.StructValidator) (e
|
|||
|
||||
// Load the Source into the EnvironmentSource koanf.Koanf.
|
||||
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)
|
||||
}
|
||||
|
@ -109,7 +108,7 @@ func (s *SecretsSource) Merge(ko *koanf.Koanf, val *schema.StructValidator) (err
|
|||
|
||||
// Load the Source into the SecretsSource koanf.Koanf.
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -300,240 +300,6 @@ var validOIDCCORSEndpoints = []string{oidc.AuthorizationEndpoint, oidc.TokenEndp
|
|||
|
||||
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{
|
||||
"authentication_backend.ldap.skip_verify": "authentication_backend.ldap.tls.skip_verify",
|
||||
"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 {
|
||||
expectedKey := reKeyReplacer.ReplaceAllString(key, "[]")
|
||||
|
||||
if utils.IsStringInSlice(expectedKey, ValidKeys) {
|
||||
if utils.IsStringInSlice(expectedKey, schema.Keys) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func TestShouldValidateGoodKeys(t *testing.T) {
|
||||
configKeys := ValidKeys
|
||||
configKeys := schema.Keys
|
||||
val := schema.NewStructValidator()
|
||||
ValidateKeys(configKeys, "AUTHELIA_", val)
|
||||
|
||||
|
@ -20,7 +20,7 @@ func TestShouldValidateGoodKeys(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestShouldNotValidateBadKeys(t *testing.T) {
|
||||
configKeys := ValidKeys
|
||||
configKeys := schema.Keys
|
||||
configKeys = append(configKeys, "bad_key")
|
||||
configKeys = append(configKeys, "totp.skewy")
|
||||
val := schema.NewStructValidator()
|
||||
|
@ -34,7 +34,7 @@ func TestShouldNotValidateBadKeys(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")
|
||||
|
||||
|
|
Loading…
Reference in New Issue