From 65e9862f9f97fbfa3d92dcd3a2e27d4a20f82420 Mon Sep 17 00:00:00 2001 From: James Elliott Date: Thu, 26 Jan 2023 13:23:47 +1100 Subject: [PATCH] docs: add json schema Signed-off-by: James Elliott --- cmd/authelia-gen/cmd_docs.go | 2 +- cmd/authelia-gen/cmd_docs_data.go | 19 +- cmd/authelia-gen/cmd_docs_jsonschema.go | 260 ++ cmd/authelia-gen/cmd_root.go | 9 +- cmd/authelia-gen/cmd_root_test.go | 2 +- cmd/authelia-gen/const.go | 67 +- cmd/authelia-gen/helpers.go | 26 + .../cli/authelia-gen/authelia-gen.md | 58 +- .../cli/authelia-gen/authelia-gen_code.md | 56 +- .../authelia-gen/authelia-gen_code_keys.md | 56 +- .../authelia-gen/authelia-gen_code_scripts.md | 56 +- .../authelia-gen/authelia-gen_code_server.md | 56 +- .../authelia-gen/authelia-gen_commit-lint.md | 56 +- .../cli/authelia-gen/authelia-gen_docs.md | 57 +- .../cli/authelia-gen/authelia-gen_docs_cli.md | 56 +- .../authelia-gen/authelia-gen_docs_data.md | 56 +- .../authelia-gen_docs_data_keys.md | 56 +- .../authelia-gen_docs_data_misc.md | 56 +- .../authelia-gen/authelia-gen_docs_date.md | 56 +- .../cli/authelia-gen/authelia-gen_github.md | 56 +- .../authelia-gen_github_issue-templates.md | 56 +- ...a-gen_github_issue-templates_bug-report.md | 56 +- ..._github_issue-templates_feature-request.md | 56 +- .../cli/authelia-gen/authelia-gen_locales.md | 56 +- docs/data/configkeys.json | 2 +- docs/static/schemas/latest/configuration.json | 2866 +++++++++++++++++ docs/static/schemas/latest/user-database.json | 71 + docs/static/schemas/v4.38/configuration.json | 2866 +++++++++++++++++ docs/static/schemas/v4.38/user-database.json | 71 + go.mod | 2 + go.sum | 10 + internal/authentication/file_user_provider.go | 26 +- .../file_user_provider_database.go | 143 +- .../file_user_provider_database_mock_test.go | 10 +- .../file_user_provider_database_test.go | 2 +- .../authentication/file_user_provider_test.go | 46 +- internal/authentication/ldap_user_provider.go | 4 +- .../authentication/ldap_user_provider_test.go | 274 +- .../authorization/access_control_query.go | 6 +- .../access_control_query_test.go | 8 +- internal/authorization/access_control_rule.go | 6 +- internal/authorization/authorizer_test.go | 142 +- internal/authorization/util.go | 2 +- internal/authorization/util_test.go | 4 +- internal/configuration/decode_hooks.go | 2 +- .../configuration/schema/access_control.go | 59 +- .../configuration/schema/authentication.go | 237 +- .../configuration/schema/configuration.go | 42 +- internal/configuration/schema/duo.go | 14 +- .../schema/identity_providers.go | 124 +- internal/configuration/schema/keys.go | 10 +- internal/configuration/schema/log.go | 14 +- internal/configuration/schema/notifier.go | 62 +- internal/configuration/schema/ntp.go | 16 +- .../configuration/schema/password_policy.go | 42 +- .../configuration/schema/privacy_policy.go | 6 +- internal/configuration/schema/regulation.go | 12 +- internal/configuration/schema/server.go | 66 +- internal/configuration/schema/session.go | 121 +- internal/configuration/schema/shared.go | 42 +- internal/configuration/schema/storage.go | 89 +- internal/configuration/schema/telemetry.go | 23 +- internal/configuration/schema/totp.go | 20 +- internal/configuration/schema/types.go | 226 +- .../configuration/schema/types_address.go | 43 + internal/configuration/schema/webauthn.go | 18 +- .../configuration/validator/access_control.go | 16 +- .../validator/access_control_test.go | 54 +- .../configuration/validator/authentication.go | 32 +- .../validator/authentication_test.go | 102 +- .../validator/configuration_test.go | 38 +- internal/configuration/validator/duo_test.go | 24 +- .../validator/identity_providers.go | 58 +- .../validator/identity_providers_test.go | 322 +- internal/configuration/validator/log_test.go | 2 +- internal/configuration/validator/notifier.go | 12 +- .../configuration/validator/notifier_test.go | 16 +- internal/configuration/validator/ntp_test.go | 2 +- .../validator/password_policy.go | 2 +- .../validator/password_policy_test.go | 54 +- .../validator/regulation_test.go | 2 +- internal/configuration/validator/server.go | 4 +- .../configuration/validator/server_test.go | 50 +- internal/configuration/validator/session.go | 46 +- .../configuration/validator/session_test.go | 221 +- internal/configuration/validator/shared.go | 4 +- .../configuration/validator/shared_test.go | 6 +- internal/configuration/validator/storage.go | 30 +- .../configuration/validator/storage_test.go | 102 +- .../configuration/validator/telemetry_test.go | 16 +- internal/configuration/validator/totp_test.go | 16 +- internal/configuration/validator/util.go | 2 +- internal/configuration/validator/util_test.go | 2 +- .../configuration/validator/webauthn_test.go | 8 +- internal/handlers/handler_authz_builder.go | 2 +- .../handlers/handler_authz_builder_test.go | 16 +- .../handler_checks_safe_redirection_test.go | 6 +- .../handlers/handler_configuration_test.go | 64 +- internal/handlers/handler_firstfactor_test.go | 8 +- internal/handlers/handler_sign_duo_test.go | 10 +- internal/handlers/handler_sign_totp_test.go | 10 +- internal/handlers/handler_user_info_test.go | 4 +- internal/logging/logger.go | 2 +- internal/logging/logger_test.go | 8 +- internal/middlewares/password_policy.go | 2 +- internal/middlewares/password_policy_test.go | 30 +- internal/mocks/authelia_ctx.go | 14 +- internal/notification/file_notifier.go | 2 +- internal/notification/smtp_auth.go | 2 +- internal/notification/smtp_notifier.go | 4 +- internal/ntp/ntp.go | 2 +- internal/ntp/ntp_test.go | 4 +- internal/ntp/types.go | 2 +- internal/oidc/authentication_test.go | 22 +- internal/oidc/client.go | 2 +- internal/oidc/client_test.go | 48 +- internal/oidc/config.go | 2 +- internal/oidc/discovery.go | 2 +- internal/oidc/discovery_test.go | 20 +- internal/oidc/keys.go | 2 +- internal/oidc/keys_blackbox_test.go | 2 +- internal/oidc/provider.go | 2 +- internal/oidc/provider_test.go | 8 +- internal/oidc/store.go | 2 +- internal/oidc/store_test.go | 28 +- internal/regulation/regulator.go | 2 +- internal/regulation/regulator_test.go | 6 +- internal/regulation/types.go | 2 +- internal/server/server_test.go | 10 +- internal/server/template.go | 6 +- internal/server/template_test.go | 9 +- internal/session/provider.go | 2 +- internal/session/provider_config.go | 6 +- internal/session/provider_test.go | 8 +- internal/session/session.go | 2 +- .../storage/sql_provider_backend_mysql.go | 2 +- .../storage/sql_provider_backend_postgres.go | 27 +- internal/suites/const.go | 6 +- internal/totp/totp.go | 4 +- internal/totp/totp_test.go | 4 +- internal/utils/crypto.go | 4 +- 141 files changed, 8737 insertions(+), 2127 deletions(-) create mode 100644 cmd/authelia-gen/cmd_docs_jsonschema.go create mode 100644 docs/static/schemas/latest/configuration.json create mode 100644 docs/static/schemas/latest/user-database.json create mode 100644 docs/static/schemas/v4.38/configuration.json create mode 100644 docs/static/schemas/v4.38/user-database.json diff --git a/cmd/authelia-gen/cmd_docs.go b/cmd/authelia-gen/cmd_docs.go index 54d1135f1..9fe694120 100644 --- a/cmd/authelia-gen/cmd_docs.go +++ b/cmd/authelia-gen/cmd_docs.go @@ -13,7 +13,7 @@ func newDocsCmd() *cobra.Command { DisableAutoGenTag: true, } - cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd()) + cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd(), newDocsJSONSchemaCmd()) return cmd } diff --git a/cmd/authelia-gen/cmd_docs_data.go b/cmd/authelia-gen/cmd_docs_data.go index 5218002a8..b2ebafcbf 100644 --- a/cmd/authelia-gen/cmd_docs_data.go +++ b/cmd/authelia-gen/cmd_docs_data.go @@ -51,25 +51,12 @@ func docsDataMiscRunE(cmd *cobra.Command, args []string) (err error) { data.CSP.TemplateDefault = strings.ReplaceAll(data.CSP.TemplateDefault, "%s", codeCSPNonce) data.CSP.TemplateDevelopment = strings.ReplaceAll(data.CSP.TemplateDevelopment, "%s", codeCSPNonce) - var ( - pathPackageJSON string - dataPackageJSON []byte - packageJSON PackageJSON - ) - - if pathPackageJSON, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagWeb, cmdFlagFileWebPackage); err != nil { + version, err := readVersion(cmd) + if err != nil { return err } - if dataPackageJSON, err = os.ReadFile(pathPackageJSON); err != nil { - return err - } - - if err = json.Unmarshal(dataPackageJSON, &packageJSON); err != nil { - return fmt.Errorf("failed to unmarshall package.json: %w", err) - } - - data.Latest = packageJSON.Version + data.Latest = version.String() var ( outputPath string diff --git a/cmd/authelia-gen/cmd_docs_jsonschema.go b/cmd/authelia-gen/cmd_docs_jsonschema.go new file mode 100644 index 000000000..2e5be6a1e --- /dev/null +++ b/cmd/authelia-gen/cmd_docs_jsonschema.go @@ -0,0 +1,260 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "reflect" + "runtime" + "strings" + + "github.com/authelia/jsonschema" + "github.com/spf13/cobra" + + "github.com/authelia/authelia/v4/internal/authentication" + "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/model" +) + +func newDocsJSONSchemaCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "json-schema", + Short: "Generate docs JSON schema", + RunE: rootSubCommandsRunE, + + DisableAutoGenTag: true, + } + + cmd.AddCommand(newDocsJSONSchemaConfigurationCmd(), newDocsJSONSchemaUserDatabaseCmd()) + + return cmd +} + +func newDocsJSONSchemaConfigurationCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "configuration", + Short: "Generate docs JSON schema for the configuration", + RunE: docsJSONSchemaConfigurationRunE, + + DisableAutoGenTag: true, + } + + return cmd +} + +func newDocsJSONSchemaUserDatabaseCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "user-database", + Short: "Generate docs JSON schema for the user database", + RunE: docsJSONSchemaUserDatabaseRunE, + + DisableAutoGenTag: true, + } + + return cmd +} + +func docsJSONSchemaConfigurationRunE(cmd *cobra.Command, args []string) (err error) { + var version *model.SemanticVersion + + if version, err = readVersion(cmd); err != nil { + return err + } + + var ( + dir, file, schemaDir string + ) + + if schemaDir, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagDirSchema); err != nil { + return err + } + + if dir, file, err = getJSONSchemaOutputPath(cmd, cmdFlagDocsStaticJSONSchemaConfiguration); err != nil { + return err + } + + return docsJSONSchemaGenerateRunE(cmd, args, version, false, schemaDir, "https://schemas.authelia.com/%s/json-schema/configuration.json", &schema.Configuration{}, dir, file) +} + +func docsJSONSchemaUserDatabaseRunE(cmd *cobra.Command, args []string) (err error) { + var version *model.SemanticVersion + + if version, err = readVersion(cmd); err != nil { + return err + } + + var ( + dir, file, schemaDir string + ) + + if schemaDir, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagDirAuthentication); err != nil { + return err + } + + if dir, file, err = getJSONSchemaOutputPath(cmd, cmdFlagDocsStaticJSONSchemaUserDatabase); err != nil { + return err + } + + return docsJSONSchemaGenerateRunE(cmd, args, version, false, schemaDir, "https://schemas.authelia.com/%s/json-schema/user-database.json", &authentication.FileUserDatabase{}, dir, file) +} + +func docsJSONSchemaGenerateRunE(cmd *cobra.Command, _ []string, version *model.SemanticVersion, patch bool, schemaDir, id string, v any, dir, file string) (err error) { + r := &jsonschema.Reflector{ + RequiredFromJSONSchemaTags: true, + Mapper: mapper, + } + + if runtime.GOOS == windows { + mapComments := map[string]string{} + + if err = jsonschema.ExtractGoComments(goModuleBase, schemaDir, mapComments); err != nil { + return err + } + + if r.CommentMap == nil { + r.CommentMap = map[string]string{} + } + + for key, comment := range mapComments { + r.CommentMap[strings.ReplaceAll(key, `\`, `/`)] = comment + } + } else { + if err = r.AddGoComments(goModuleBase, schemaDir); err != nil { + return err + } + } + + var ( + latest, next bool + ) + + latest, _ = cmd.Flags().GetBool(cmdFlagLatest) + next, _ = cmd.Flags().GetBool(cmdFlagNext) + + var schemaVersion string + + if patch { + schemaVersion = fmt.Sprintf("v%d.%d.%d", version.Major, version.Minor, version.Patch) + if next { + schemaVersion = fmt.Sprintf("v%d.%d.%d", version.Major, version.Minor+1, 0) + } + } else { + schemaVersion = fmt.Sprintf("v%d.%d", version.Major, version.Minor) + if next { + schemaVersion = fmt.Sprintf("v%d.%d", version.Major, version.Minor+1) + } + } + + schema := r.Reflect(v) + + schema.ID = jsonschema.ID(fmt.Sprintf(id, schemaVersion)) + + if err = writeJSONSchema(schema, dir, schemaVersion, file); err != nil { + return err + } + + if latest { + if err = writeJSONSchema(schema, dir, "latest", file); err != nil { + return err + } + } + + return nil +} + +func writeJSONSchema(schema *jsonschema.Schema, dir, version, file string) (err error) { + var ( + data []byte + f *os.File + ) + + if data, err = json.MarshalIndent(schema, "", " "); err != nil { + return err + } + + if _, err = os.Stat(filepath.Join(dir, version)); err != nil && os.IsNotExist(err) { + if err = os.Mkdir(filepath.Join(dir, version), 0755); err != nil { + return err + } + } + + if f, err = os.Create(filepath.Join(dir, version, file)); err != nil { + return err + } + + if _, err = f.Write(data); err != nil { + return err + } + + return f.Close() +} + +func getJSONSchemaOutputPath(cmd *cobra.Command, flag string) (dir, file string, err error) { + if dir, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagDocs, cmdFlagDocsStatic, cmdFlagDocsStaticJSONSchemas); err != nil { + return "", "", err + } + + if file, err = cmd.Flags().GetString(flag); err != nil { + return "", "", err + } + + return dir, file, nil +} + +func mapper(t reflect.Type) *jsonschema.Schema { + switch t.String() { + case "regexp.Regexp", "*regexp.Regexp": + return &jsonschema.Schema{ + Type: "string", + Format: "regex", + } + case "time.Duration", "*time.Duration": + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + { + Type: "string", + Pattern: `^\d+\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\s*\d+\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$`, + Comments: "Example comment", + }, + { + Type: "integer", + Description: "The duration in seconds", + }, + }, + } + case "schema.CryptographicKey": + return &jsonschema.Schema{ + Type: "string", + } + case "schema.CryptographicPrivateKey": + return &jsonschema.Schema{ + Type: "string", + Pattern: `^-{5}(BEGIN ((RSA|EC) )?PRIVATE KEY-{5}\n([a-zA-Z0-9/+]{1,64}\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\n-{5}END ((RSA|EC) )?PRIVATE KEY-{5}\n?)+$`, + } + case "rsa.PrivateKey", "*rsa.PrivateKey", "ecdsa.PrivateKey", "*.ecdsa.PrivateKey": + return &jsonschema.Schema{ + Type: "string", + } + case "mail.Address", "*mail.Address": + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + { + Type: "string", + Pattern: `^[a-zA-Z0-9.!#$%&'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$`, + }, + { + Type: "string", + Pattern: `^[^<]+ <[a-zA-Z0-9.!#$%&'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*>$`, + }, + }, + } + case "schema.CSPTemplate": + return &jsonschema.Schema{ + Type: "string", + Default: buildCSP(codeCSPProductionDefaultSrc, codeCSPValuesCommon, codeCSPValuesProduction), + } + } + + return nil +} diff --git a/cmd/authelia-gen/cmd_root.go b/cmd/authelia-gen/cmd_root.go index b20acf2d9..a81026fd8 100644 --- a/cmd/authelia-gen/cmd_root.go +++ b/cmd/authelia-gen/cmd_root.go @@ -32,6 +32,8 @@ func newRootCmd() *cobra.Command { cmd.PersistentFlags().String(cmdFlagBugReport, fileGitHubIssueTemplateBR, "Sets the path of the bug report issue template file") cmd.PersistentFlags().Int(cmdFlagVersions, 5, "the maximum number of minor versions to list in output templates") cmd.PersistentFlags().String(cmdFlagDirLocales, dirLocales, "The locales directory in relation to the root") + cmd.PersistentFlags().String(cmdFlagDirSchema, "internal/configuration/schema", "The schema directory in relation to the root") + cmd.PersistentFlags().String(cmdFlagDirAuthentication, "internal/authentication", "The authentication directory in relation to the root") cmd.PersistentFlags().String(cmdFlagFileWebI18N, fileWebI18NIndex, "The i18n typescript configuration file in relation to the web directory") cmd.PersistentFlags().String(cmdFlagFileWebPackage, fileWebPackage, "The node package configuration file in relation to the web directory") cmd.PersistentFlags().String(cmdFlagDocsDataLanguages, fileDocsDataLanguages, "The languages docs data file in relation to the docs data folder") @@ -39,16 +41,21 @@ func newRootCmd() *cobra.Command { cmd.PersistentFlags().String(cmdFlagDocsCLIReference, dirDocsCLIReference, "The directory to store the markdown in") cmd.PersistentFlags().String(cmdFlagDocs, dirDocs, "The directory with the docs") cmd.PersistentFlags().String(cmdFlagDocsContent, dirDocsContent, "The directory with the docs content") + cmd.PersistentFlags().String(cmdFlagDocsStatic, dirDocsStatic, "The directory with the docs static files") + cmd.PersistentFlags().String(cmdFlagDocsStaticJSONSchemas, dirDocsStaticJSONSchemas, "The directory with the docs static JSONSchema files") cmd.PersistentFlags().String(cmdFlagDocsData, dirDocsData, "The directory with the docs data") cmd.PersistentFlags().String(cmdFlagFileConfigKeys, fileCodeConfigKeys, "Sets the path of the keys file") cmd.PersistentFlags().String(cmdFlagDocsDataKeys, fileDocsDataConfigKeys, "Sets the path of the docs keys file") cmd.PersistentFlags().String(cmdFlagPackageConfigKeys, pkgConfigSchema, "Sets the package name of the keys file") cmd.PersistentFlags().String(cmdFlagFileScriptsGen, fileScriptsGen, "Sets the path of the authelia-scripts gen file") + cmd.PersistentFlags().String(cmdFlagDocsStaticJSONSchemaConfiguration, fileDocsStaticJSONSchemasConfiguration, "Sets the path of the configuration JSONSchema") + cmd.PersistentFlags().String(cmdFlagDocsStaticJSONSchemaUserDatabase, fileDocsStaticJSONSchemasUserDatabase, "Sets the path of the user database JSONSchema") cmd.PersistentFlags().String(cmdFlagFileServerGenerated, fileServerGenerated, "Sets the path of the server generated file") cmd.PersistentFlags().String(cmdFlagPackageScriptsGen, pkgScriptsGen, "Sets the package name of the authelia-scripts gen file") cmd.PersistentFlags().String(cmdFlagFileConfigCommitLint, fileCICommitLintConfig, "The commit lint javascript configuration file in relation to the root") cmd.PersistentFlags().String(cmdFlagFileDocsCommitMsgGuidelines, fileDocsCommitMessageGuidelines, "The commit message guidelines documentation file in relation to the root") - + cmd.PersistentFlags().Bool("latest", false, "Enables latest functionality with several generators like the JSON Schema generator") + cmd.PersistentFlags().Bool("next", false, "Enables next functionality with several generators like the JSON Schema generator") cmd.AddCommand(newCodeCmd(), newDocsCmd(), newGitHubCmd(), newLocalesCmd(), newCommitLintCmd()) return cmd diff --git a/cmd/authelia-gen/cmd_root_test.go b/cmd/authelia-gen/cmd_root_test.go index 1579364eb..a9154c87c 100644 --- a/cmd/authelia-gen/cmd_root_test.go +++ b/cmd/authelia-gen/cmd_root_test.go @@ -90,7 +90,7 @@ func TestSortCmds(t *testing.T) { { "ShouldSortDocsCmd", newDocsCmd(), - []string{"cli", "data", "date"}, + []string{"cli", "data", "json-schema", "date"}, }, { "ShouldSortGitHubCmd", diff --git a/cmd/authelia-gen/const.go b/cmd/authelia-gen/const.go index 811390896..671e50d0b 100644 --- a/cmd/authelia-gen/const.go +++ b/cmd/authelia-gen/const.go @@ -18,15 +18,20 @@ const ( fileServerGenerated = "internal/server/gen.go" fileScriptsGen = "cmd/authelia-scripts/cmd/gen.go" - dirDocs = "docs" - dirDocsContent = "content" - dirDocsData = "data" - dirDocsCLIReference = "en/reference/cli" + dirDocs = "docs" + dirDocsContent = "content" + dirDocsStatic = "static" + dirDocsStaticJSONSchemas = "schemas" + dirDocsData = "data" + dirDocsCLIReference = "en/reference/cli" fileDocsDataLanguages = "languages.json" fileDocsDataMisc = "misc.json" fileDocsDataConfigKeys = "configkeys.json" + fileDocsStaticJSONSchemasConfiguration = "configuration.json" + fileDocsStaticJSONSchemasUserDatabase = "user-database.json" + fileGitHubIssueTemplateFR = ".github/ISSUE_TEMPLATE/feature-request.yml" fileGitHubIssueTemplateBR = ".github/ISSUE_TEMPLATE/bug-report.yml" ) @@ -69,25 +74,33 @@ const ( ) const ( - cmdFlagRoot = "dir.root" - cmdFlagWeb = "dir.web" - cmdFlagFileWebI18N = "file.web.i18n" - cmdFlagFileWebPackage = "file.web.package" - cmdFlagDocs = "dir.docs" - cmdFlagDirLocales = "dir.locales" - cmdFlagDocsCLIReference = "dir.docs.cli-reference" - cmdFlagDocsContent = "dir.docs.content" - cmdFlagDocsData = "dir.docs.data" - cmdFlagDocsDataMisc = "file.docs.data.misc" - cmdFlagDocsDataKeys = "file.docs.data.keys" - cmdFlagDocsDataLanguages = "file.docs.data.languages" - cmdFlagFileConfigKeys = "file.configuration-keys" - cmdFlagFileScriptsGen = "file.scripts.gen" - cmdFlagFileServerGenerated = "file.server.generated" - cmdFlagFileConfigCommitLint = "file.commit-lint-config" - cmdFlagFileDocsCommitMsgGuidelines = "file.docs-commit-msg-guidelines" - cmdFlagFeatureRequest = "file.feature-request" - cmdFlagBugReport = "file.bug-report" + cmdFlagRoot = "dir.root" + cmdFlagWeb = "dir.web" + cmdFlagFileWebI18N = "file.web.i18n" + cmdFlagFileWebPackage = "file.web.package" + cmdFlagDocs = "dir.docs" + cmdFlagDirLocales = "dir.locales" + cmdFlagDirSchema = "dir.schema" + cmdFlagDirAuthentication = "dir.authentication" + cmdFlagDocsCLIReference = "dir.docs.cli-reference" + cmdFlagDocsContent = "dir.docs.content" + cmdFlagDocsStatic = "dir.docs.static" + cmdFlagDocsStaticJSONSchemas = "dir.docs.static.json-schemas" + cmdFlagDocsData = "dir.docs.data" + cmdFlagDocsDataMisc = "file.docs.data.misc" + cmdFlagDocsDataKeys = "file.docs.data.keys" + cmdFlagDocsDataLanguages = "file.docs.data.languages" + cmdFlagDocsStaticJSONSchemaConfiguration = "file.docs.static.json-schemas.configuration" + cmdFlagDocsStaticJSONSchemaUserDatabase = "file.docs.static.json-schemas.user-database" + cmdFlagFileConfigKeys = "file.configuration-keys" + cmdFlagFileScriptsGen = "file.scripts.gen" + cmdFlagFileServerGenerated = "file.server.generated" + cmdFlagFileConfigCommitLint = "file.commit-lint-config" + cmdFlagFileDocsCommitMsgGuidelines = "file.docs-commit-msg-guidelines" + cmdFlagFeatureRequest = "file.feature-request" + cmdFlagBugReport = "file.bug-report" + cmdFlagLatest = "latest" + cmdFlagNext = "next" cmdFlagExclude = "exclude" cmdFlagVersions = "versions" @@ -102,6 +115,14 @@ const ( codeCSPNonce = "${NONCE}" ) +const ( + goModuleBase = "github.com/authelia/authelia/v4" +) + +const ( + windows = "windows" +) + var ( codeCSPValuesCommon = []CSPValue{ {Name: "default-src", Value: ""}, diff --git a/cmd/authelia-gen/helpers.go b/cmd/authelia-gen/helpers.go index c244ad06b..608194fc3 100644 --- a/cmd/authelia-gen/helpers.go +++ b/cmd/authelia-gen/helpers.go @@ -3,18 +3,22 @@ package main import ( "crypto/ecdsa" "crypto/rsa" + "encoding/json" "fmt" "net/mail" "net/url" + "os" "path/filepath" "reflect" "regexp" "strings" "time" + "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/authelia/authelia/v4/internal/configuration/schema" + "github.com/authelia/authelia/v4/internal/model" ) func getPFlagPath(flags *pflag.FlagSet, flagNames ...string) (fullPath string, err error) { @@ -86,6 +90,28 @@ func containsType(needle reflect.Type, haystack []reflect.Type) (contains bool) return false } +func readVersion(cmd *cobra.Command) (version *model.SemanticVersion, err error) { + var ( + pathPackageJSON string + dataPackageJSON []byte + packageJSON PackageJSON + ) + + if pathPackageJSON, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagWeb, cmdFlagFileWebPackage); err != nil { + return nil, err + } + + if dataPackageJSON, err = os.ReadFile(pathPackageJSON); err != nil { + return nil, err + } + + if err = json.Unmarshal(dataPackageJSON, &packageJSON); err != nil { + return nil, fmt.Errorf("failed to unmarshall package.json: %w", err) + } + + return model.NewSemanticVersion(packageJSON.Version) +} + //nolint:gocyclo func readTags(prefix string, t reflect.Type, envSkip bool) (tags []string) { tags = make([]string, 0) diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen.md index 055334a34..2d82a82d5 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen.md @@ -23,31 +23,39 @@ authelia-gen [flags] ### Options ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - -h, --help help for authelia-gen - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + -h, --help help for authelia-gen + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code.md index ab1f13023..195110066 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code.md @@ -29,30 +29,38 @@ authelia-gen code [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_keys.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_keys.md index 06741e136..d23574b37 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_keys.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_keys.md @@ -29,30 +29,38 @@ authelia-gen code keys [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_scripts.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_scripts.md index 937b2264a..b14ec5eb1 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_scripts.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_scripts.md @@ -29,30 +29,38 @@ authelia-gen code scripts [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_server.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_server.md index e9c200b49..ad13cf8fa 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_server.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_code_server.md @@ -29,30 +29,38 @@ authelia-gen code server [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_commit-lint.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_commit-lint.md index f8f6cd368..7f938d378 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_commit-lint.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_commit-lint.md @@ -29,30 +29,38 @@ authelia-gen commit-lint [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs.md index c7b50013e..03870f0ce 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs.md @@ -29,30 +29,38 @@ authelia-gen docs [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO @@ -61,4 +69,5 @@ authelia-gen docs [flags] * [authelia-gen docs cli](authelia-gen_docs_cli.md) - Generate CLI docs * [authelia-gen docs data](authelia-gen_docs_data.md) - Generate docs data files * [authelia-gen docs date](authelia-gen_docs_date.md) - Generate doc dates +* [authelia-gen docs json-schema](authelia-gen_docs_json-schema.md) - Generate docs JSON schema diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_cli.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_cli.md index be8cf343e..7aacc39c4 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_cli.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_cli.md @@ -29,30 +29,38 @@ authelia-gen docs cli [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data.md index ab8df382c..21857f904 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data.md @@ -29,30 +29,38 @@ authelia-gen docs data [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_keys.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_keys.md index f269ee95e..b08d9daa4 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_keys.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_keys.md @@ -29,30 +29,38 @@ authelia-gen docs data keys [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_misc.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_misc.md index 2ea33dd9e..671efccd4 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_misc.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_data_misc.md @@ -29,30 +29,38 @@ authelia-gen docs data misc [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_date.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_date.md index aef280f65..6816d85c8 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_date.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_docs_date.md @@ -31,30 +31,38 @@ authelia-gen docs date [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github.md index 29f7b72fc..3e3f17be1 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github.md @@ -29,30 +29,38 @@ authelia-gen github [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates.md index 35446870e..287b0bae7 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates.md @@ -29,30 +29,38 @@ authelia-gen github issue-templates [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_bug-report.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_bug-report.md index 396e4598a..40f00ca6e 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_bug-report.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_bug-report.md @@ -29,30 +29,38 @@ authelia-gen github issue-templates bug-report [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_feature-request.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_feature-request.md index 003c13494..9bbccb9fa 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_feature-request.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_github_issue-templates_feature-request.md @@ -29,30 +29,38 @@ authelia-gen github issue-templates feature-request [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/content/en/reference/cli/authelia-gen/authelia-gen_locales.md b/docs/content/en/reference/cli/authelia-gen/authelia-gen_locales.md index 3f64f2781..714212c3c 100644 --- a/docs/content/en/reference/cli/authelia-gen/authelia-gen_locales.md +++ b/docs/content/en/reference/cli/authelia-gen/authelia-gen_locales.md @@ -29,30 +29,38 @@ authelia-gen locales [flags] ### Options inherited from parent commands ``` - -C, --cwd string Sets the CWD for git commands - --dir.docs string The directory with the docs (default "docs") - --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") - --dir.docs.content string The directory with the docs content (default "content") - --dir.docs.data string The directory with the docs data (default "data") - --dir.locales string The locales directory in relation to the root (default "internal/server/locales") - -d, --dir.root string The repository root (default "./") - --dir.web string The repository web directory in relation to the root directory (default "web") - -X, --exclude strings Sets the names of excluded generators - --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") - --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") - --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") - --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") - --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") - --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") - --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") - --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") - --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") - --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") - --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") - --file.web.package string The node package configuration file in relation to the web directory (default "package.json") - --package.configuration.keys string Sets the package name of the keys file (default "schema") - --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") - --versions int the maximum number of minor versions to list in output templates (default 5) + -C, --cwd string Sets the CWD for git commands + --dir.authentication string The authentication directory in relation to the root (default "internal/authentication") + --dir.docs string The directory with the docs (default "docs") + --dir.docs.cli-reference string The directory to store the markdown in (default "en/reference/cli") + --dir.docs.content string The directory with the docs content (default "content") + --dir.docs.data string The directory with the docs data (default "data") + --dir.docs.static string The directory with the docs static files (default "static") + --dir.docs.static.json-schemas string The directory with the docs static JSONSchema files (default "schemas") + --dir.locales string The locales directory in relation to the root (default "internal/server/locales") + -d, --dir.root string The repository root (default "./") + --dir.schema string The schema directory in relation to the root (default "internal/configuration/schema") + --dir.web string The repository web directory in relation to the root directory (default "web") + -X, --exclude strings Sets the names of excluded generators + --file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") + --file.commit-lint-config string The commit lint javascript configuration file in relation to the root (default ".commitlintrc.js") + --file.configuration-keys string Sets the path of the keys file (default "internal/configuration/schema/keys.go") + --file.docs-commit-msg-guidelines string The commit message guidelines documentation file in relation to the root (default "docs/content/en/contributing/guidelines/commit-message.md") + --file.docs.data.keys string Sets the path of the docs keys file (default "configkeys.json") + --file.docs.data.languages string The languages docs data file in relation to the docs data folder (default "languages.json") + --file.docs.data.misc string The misc docs data file in relation to the docs data folder (default "misc.json") + --file.docs.static.json-schemas.configuration string Sets the path of the configuration JSONSchema (default "configuration.json") + --file.docs.static.json-schemas.user-database string Sets the path of the user database JSONSchema (default "user-database.json") + --file.feature-request string Sets the path of the feature request issue template file (default ".github/ISSUE_TEMPLATE/feature-request.yml") + --file.scripts.gen string Sets the path of the authelia-scripts gen file (default "cmd/authelia-scripts/cmd/gen.go") + --file.server.generated string Sets the path of the server generated file (default "internal/server/gen.go") + --file.web.i18n string The i18n typescript configuration file in relation to the web directory (default "src/i18n/index.ts") + --file.web.package string The node package configuration file in relation to the web directory (default "package.json") + --latest Enables latest functionality with several generators like the JSON Schema generator + --next Enables next functionality with several generators like the JSON Schema generator + --package.configuration.keys string Sets the package name of the keys file (default "schema") + --package.scripts.gen string Sets the package name of the authelia-scripts gen file (default "cmd") + --versions int the maximum number of minor versions to list in output templates (default 5) ``` ### SEE ALSO diff --git a/docs/data/configkeys.json b/docs/data/configkeys.json index a579aa18f..6274fdd65 100644 --- a/docs/data/configkeys.json +++ b/docs/data/configkeys.json @@ -1 +1 @@ -[{"path":"theme","secret":false,"env":"AUTHELIA_THEME"},{"path":"certificates_directory","secret":false,"env":"AUTHELIA_CERTIFICATES_DIRECTORY"},{"path":"jwt_secret","secret":true,"env":"AUTHELIA_JWT_SECRET_FILE"},{"path":"default_redirection_url","secret":false,"env":"AUTHELIA_DEFAULT_REDIRECTION_URL"},{"path":"default_2fa_method","secret":false,"env":"AUTHELIA_DEFAULT_2FA_METHOD"},{"path":"log.level","secret":false,"env":"AUTHELIA_LOG_LEVEL"},{"path":"log.format","secret":false,"env":"AUTHELIA_LOG_FORMAT"},{"path":"log.file_path","secret":false,"env":"AUTHELIA_LOG_FILE_PATH"},{"path":"log.keep_stdout","secret":false,"env":"AUTHELIA_LOG_KEEP_STDOUT"},{"path":"identity_providers.oidc.hmac_secret","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE"},{"path":"identity_providers.oidc.issuer_certificate_chain","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE"},{"path":"identity_providers.oidc.issuer_private_key","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE"},{"path":"identity_providers.oidc.access_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ACCESS_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.authorize_code_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_AUTHORIZE_CODE_LIFESPAN"},{"path":"identity_providers.oidc.id_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ID_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.refresh_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_REFRESH_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.enable_client_debug_messages","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_CLIENT_DEBUG_MESSAGES"},{"path":"identity_providers.oidc.minimum_parameter_entropy","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_MINIMUM_PARAMETER_ENTROPY"},{"path":"identity_providers.oidc.enforce_pkce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENFORCE_PKCE"},{"path":"identity_providers.oidc.enable_pkce_plain_challenge","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_PKCE_PLAIN_CHALLENGE"},{"path":"identity_providers.oidc.pushed_authorizations.enforce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_PUSHED_AUTHORIZATIONS_ENFORCE"},{"path":"identity_providers.oidc.pushed_authorizations.context_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_PUSHED_AUTHORIZATIONS_CONTEXT_LIFESPAN"},{"path":"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS_FROM_CLIENT_REDIRECT_URIS"},{"path":"identity_providers.oidc","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC"},{"path":"authentication_backend.password_reset.disable","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_DISABLE"},{"path":"authentication_backend.password_reset.custom_url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_CUSTOM_URL"},{"path":"authentication_backend.refresh_interval","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_REFRESH_INTERVAL"},{"path":"authentication_backend.file.path","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PATH"},{"path":"authentication_backend.file.watch","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_WATCH"},{"path":"authentication_backend.file.password.algorithm","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ALGORITHM"},{"path":"authentication_backend.file.password.argon2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_VARIANT"},{"path":"authentication_backend.file.password.argon2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_ITERATIONS"},{"path":"authentication_backend.file.password.argon2.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_MEMORY"},{"path":"authentication_backend.file.password.argon2.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_PARALLELISM"},{"path":"authentication_backend.file.password.argon2.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_KEY_LENGTH"},{"path":"authentication_backend.file.password.argon2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_SALT_LENGTH"},{"path":"authentication_backend.file.password.sha2crypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_VARIANT"},{"path":"authentication_backend.file.password.sha2crypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.sha2crypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.pbkdf2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_VARIANT"},{"path":"authentication_backend.file.password.pbkdf2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_ITERATIONS"},{"path":"authentication_backend.file.password.pbkdf2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_SALT_LENGTH"},{"path":"authentication_backend.file.password.bcrypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_VARIANT"},{"path":"authentication_backend.file.password.bcrypt.cost","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_COST"},{"path":"authentication_backend.file.password.scrypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.scrypt.block_size","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_BLOCK_SIZE"},{"path":"authentication_backend.file.password.scrypt.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_PARALLELISM"},{"path":"authentication_backend.file.password.scrypt.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_KEY_LENGTH"},{"path":"authentication_backend.file.password.scrypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ITERATIONS"},{"path":"authentication_backend.file.password.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_MEMORY"},{"path":"authentication_backend.file.password.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PARALLELISM"},{"path":"authentication_backend.file.password.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_KEY_LENGTH"},{"path":"authentication_backend.file.password.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SALT_LENGTH"},{"path":"authentication_backend.file.search.email","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_EMAIL"},{"path":"authentication_backend.file.search.case_insensitive","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_CASE_INSENSITIVE"},{"path":"authentication_backend.ldap.address","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDRESS"},{"path":"authentication_backend.ldap.implementation","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_IMPLEMENTATION"},{"path":"authentication_backend.ldap.timeout","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TIMEOUT"},{"path":"authentication_backend.ldap.start_tls","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_START_TLS"},{"path":"authentication_backend.ldap.tls.minimum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MINIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.maximum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MAXIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.skip_verify","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SKIP_VERIFY"},{"path":"authentication_backend.ldap.tls.server_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SERVER_NAME"},{"path":"authentication_backend.ldap.tls.private_key","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_PRIVATE_KEY_FILE"},{"path":"authentication_backend.ldap.tls.certificate_chain","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"authentication_backend.ldap.base_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_BASE_DN"},{"path":"authentication_backend.ldap.additional_users_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_USERS_DN"},{"path":"authentication_backend.ldap.users_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERS_FILTER"},{"path":"authentication_backend.ldap.additional_groups_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_GROUPS_DN"},{"path":"authentication_backend.ldap.groups_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUPS_FILTER"},{"path":"authentication_backend.ldap.group_search_mode","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUP_SEARCH_MODE"},{"path":"authentication_backend.ldap.attributes.distinguished_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISTINGUISHED_NAME"},{"path":"authentication_backend.ldap.attributes.username","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_USERNAME"},{"path":"authentication_backend.ldap.attributes.display_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISPLAY_NAME"},{"path":"authentication_backend.ldap.attributes.mail","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MAIL"},{"path":"authentication_backend.ldap.attributes.member_of","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MEMBER_OF"},{"path":"authentication_backend.ldap.attributes.group_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_GROUP_NAME"},{"path":"authentication_backend.ldap.permit_referrals","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_REFERRALS"},{"path":"authentication_backend.ldap.permit_unauthenticated_bind","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_UNAUTHENTICATED_BIND"},{"path":"authentication_backend.ldap.permit_feature_detection_failure","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_FEATURE_DETECTION_FAILURE"},{"path":"authentication_backend.ldap.user","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USER"},{"path":"authentication_backend.ldap.password","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE"},{"path":"session.secret","secret":true,"env":"AUTHELIA_SESSION_SECRET_FILE"},{"path":"session.name","secret":false,"env":"AUTHELIA_SESSION_NAME"},{"path":"session.domain","secret":false,"env":"AUTHELIA_SESSION_DOMAIN"},{"path":"session.same_site","secret":false,"env":"AUTHELIA_SESSION_SAME_SITE"},{"path":"session.expiration","secret":false,"env":"AUTHELIA_SESSION_EXPIRATION"},{"path":"session.inactivity","secret":false,"env":"AUTHELIA_SESSION_INACTIVITY"},{"path":"session.remember_me","secret":false,"env":"AUTHELIA_SESSION_REMEMBER_ME"},{"path":"session","secret":false,"env":"AUTHELIA_SESSION"},{"path":"session.redis.host","secret":false,"env":"AUTHELIA_SESSION_REDIS_HOST"},{"path":"session.redis.port","secret":false,"env":"AUTHELIA_SESSION_REDIS_PORT"},{"path":"session.redis.username","secret":false,"env":"AUTHELIA_SESSION_REDIS_USERNAME"},{"path":"session.redis.password","secret":true,"env":"AUTHELIA_SESSION_REDIS_PASSWORD_FILE"},{"path":"session.redis.database_index","secret":false,"env":"AUTHELIA_SESSION_REDIS_DATABASE_INDEX"},{"path":"session.redis.maximum_active_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MAXIMUM_ACTIVE_CONNECTIONS"},{"path":"session.redis.minimum_idle_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MINIMUM_IDLE_CONNECTIONS"},{"path":"session.redis.tls.minimum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MINIMUM_VERSION"},{"path":"session.redis.tls.maximum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MAXIMUM_VERSION"},{"path":"session.redis.tls.skip_verify","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SKIP_VERIFY"},{"path":"session.redis.tls.server_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SERVER_NAME"},{"path":"session.redis.tls.private_key","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_PRIVATE_KEY_FILE"},{"path":"session.redis.tls.certificate_chain","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"session.redis.high_availability.sentinel_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_NAME"},{"path":"session.redis.high_availability.sentinel_username","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_USERNAME"},{"path":"session.redis.high_availability.sentinel_password","secret":true,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE"},{"path":"session.redis.high_availability.route_by_latency","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_BY_LATENCY"},{"path":"session.redis.high_availability.route_randomly","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_RANDOMLY"},{"path":"totp.disable","secret":false,"env":"AUTHELIA_TOTP_DISABLE"},{"path":"totp.issuer","secret":false,"env":"AUTHELIA_TOTP_ISSUER"},{"path":"totp.algorithm","secret":false,"env":"AUTHELIA_TOTP_ALGORITHM"},{"path":"totp.digits","secret":false,"env":"AUTHELIA_TOTP_DIGITS"},{"path":"totp.period","secret":false,"env":"AUTHELIA_TOTP_PERIOD"},{"path":"totp.skew","secret":false,"env":"AUTHELIA_TOTP_SKEW"},{"path":"totp.secret_size","secret":false,"env":"AUTHELIA_TOTP_SECRET_SIZE"},{"path":"duo_api.disable","secret":false,"env":"AUTHELIA_DUO_API_DISABLE"},{"path":"duo_api.hostname","secret":false,"env":"AUTHELIA_DUO_API_HOSTNAME"},{"path":"duo_api.integration_key","secret":true,"env":"AUTHELIA_DUO_API_INTEGRATION_KEY_FILE"},{"path":"duo_api.secret_key","secret":true,"env":"AUTHELIA_DUO_API_SECRET_KEY_FILE"},{"path":"duo_api.enable_self_enrollment","secret":false,"env":"AUTHELIA_DUO_API_ENABLE_SELF_ENROLLMENT"},{"path":"access_control.default_policy","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_DEFAULT_POLICY"},{"path":"ntp.address","secret":false,"env":"AUTHELIA_NTP_ADDRESS"},{"path":"ntp.version","secret":false,"env":"AUTHELIA_NTP_VERSION"},{"path":"ntp.max_desync","secret":false,"env":"AUTHELIA_NTP_MAX_DESYNC"},{"path":"ntp.disable_startup_check","secret":false,"env":"AUTHELIA_NTP_DISABLE_STARTUP_CHECK"},{"path":"ntp.disable_failure","secret":false,"env":"AUTHELIA_NTP_DISABLE_FAILURE"},{"path":"regulation.max_retries","secret":false,"env":"AUTHELIA_REGULATION_MAX_RETRIES"},{"path":"regulation.find_time","secret":false,"env":"AUTHELIA_REGULATION_FIND_TIME"},{"path":"regulation.ban_time","secret":false,"env":"AUTHELIA_REGULATION_BAN_TIME"},{"path":"storage.local.path","secret":false,"env":"AUTHELIA_STORAGE_LOCAL_PATH"},{"path":"storage.mysql.address","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_ADDRESS"},{"path":"storage.mysql.database","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_DATABASE"},{"path":"storage.mysql.username","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_USERNAME"},{"path":"storage.mysql.password","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE"},{"path":"storage.mysql.timeout","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TIMEOUT"},{"path":"storage.mysql.host","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_HOST"},{"path":"storage.mysql.port","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_PORT"},{"path":"storage.mysql.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MINIMUM_VERSION"},{"path":"storage.mysql.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MAXIMUM_VERSION"},{"path":"storage.mysql.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SKIP_VERIFY"},{"path":"storage.mysql.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SERVER_NAME"},{"path":"storage.mysql.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_TLS_PRIVATE_KEY_FILE"},{"path":"storage.mysql.tls.certificate_chain","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"storage.postgres.address","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_ADDRESS"},{"path":"storage.postgres.database","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_DATABASE"},{"path":"storage.postgres.username","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_USERNAME"},{"path":"storage.postgres.password","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE"},{"path":"storage.postgres.timeout","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TIMEOUT"},{"path":"storage.postgres.host","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_HOST"},{"path":"storage.postgres.port","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_PORT"},{"path":"storage.postgres.schema","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SCHEMA"},{"path":"storage.postgres.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MINIMUM_VERSION"},{"path":"storage.postgres.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MAXIMUM_VERSION"},{"path":"storage.postgres.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SKIP_VERIFY"},{"path":"storage.postgres.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SERVER_NAME"},{"path":"storage.postgres.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_PRIVATE_KEY_FILE"},{"path":"storage.postgres.tls.certificate_chain","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"storage.postgres.ssl.mode","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_MODE"},{"path":"storage.postgres.ssl.root_certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_ROOT_CERTIFICATE"},{"path":"storage.postgres.ssl.certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_CERTIFICATE"},{"path":"storage.postgres.ssl.key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_KEY_FILE"},{"path":"storage.encryption_key","secret":true,"env":"AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE"},{"path":"notifier.disable_startup_check","secret":false,"env":"AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK"},{"path":"notifier.filesystem.filename","secret":false,"env":"AUTHELIA_NOTIFIER_FILESYSTEM_FILENAME"},{"path":"notifier.smtp.address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_ADDRESS"},{"path":"notifier.smtp.timeout","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TIMEOUT"},{"path":"notifier.smtp.username","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_USERNAME"},{"path":"notifier.smtp.password","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE"},{"path":"notifier.smtp.identifier","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_IDENTIFIER"},{"path":"notifier.smtp.sender","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SENDER"},{"path":"notifier.smtp.subject","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SUBJECT"},{"path":"notifier.smtp.startup_check_address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_STARTUP_CHECK_ADDRESS"},{"path":"notifier.smtp.disable_require_tls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_REQUIRE_TLS"},{"path":"notifier.smtp.disable_html_emails","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_HTML_EMAILS"},{"path":"notifier.smtp.disable_starttls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_STARTTLS"},{"path":"notifier.smtp.tls.minimum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MINIMUM_VERSION"},{"path":"notifier.smtp.tls.maximum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MAXIMUM_VERSION"},{"path":"notifier.smtp.tls.skip_verify","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SKIP_VERIFY"},{"path":"notifier.smtp.tls.server_name","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SERVER_NAME"},{"path":"notifier.smtp.tls.private_key","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_PRIVATE_KEY_FILE"},{"path":"notifier.smtp.tls.certificate_chain","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"notifier.smtp.host","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_HOST"},{"path":"notifier.smtp.port","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_PORT"},{"path":"notifier.template_path","secret":false,"env":"AUTHELIA_NOTIFIER_TEMPLATE_PATH"},{"path":"server.address","secret":false,"env":"AUTHELIA_SERVER_ADDRESS"},{"path":"server.asset_path","secret":false,"env":"AUTHELIA_SERVER_ASSET_PATH"},{"path":"server.disable_healthcheck","secret":false,"env":"AUTHELIA_SERVER_DISABLE_HEALTHCHECK"},{"path":"server.tls.certificate","secret":false,"env":"AUTHELIA_SERVER_TLS_CERTIFICATE"},{"path":"server.tls.key","secret":true,"env":"AUTHELIA_SERVER_TLS_KEY_FILE"},{"path":"server.headers.csp_template","secret":false,"env":"AUTHELIA_SERVER_HEADERS_CSP_TEMPLATE"},{"path":"server.endpoints.enable_pprof","secret":false,"env":"AUTHELIA_SERVER_ENDPOINTS_ENABLE_PPROF"},{"path":"server.endpoints.enable_expvars","secret":false,"env":"AUTHELIA_SERVER_ENDPOINTS_ENABLE_EXPVARS"},{"path":"server.buffers.read","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_READ"},{"path":"server.buffers.write","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_WRITE"},{"path":"server.timeouts.read","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_READ"},{"path":"server.timeouts.write","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_WRITE"},{"path":"server.timeouts.idle","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_IDLE"},{"path":"server.host","secret":false,"env":"AUTHELIA_SERVER_HOST"},{"path":"server.port","secret":false,"env":"AUTHELIA_SERVER_PORT"},{"path":"server.path","secret":false,"env":"AUTHELIA_SERVER_PATH"},{"path":"telemetry.metrics.enabled","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ENABLED"},{"path":"telemetry.metrics.address","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ADDRESS"},{"path":"telemetry.metrics.buffers.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_READ"},{"path":"telemetry.metrics.buffers.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_WRITE"},{"path":"telemetry.metrics.timeouts.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_READ"},{"path":"telemetry.metrics.timeouts.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_WRITE"},{"path":"telemetry.metrics.timeouts.idle","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_IDLE"},{"path":"webauthn.disable","secret":false,"env":"AUTHELIA_WEBAUTHN_DISABLE"},{"path":"webauthn.display_name","secret":false,"env":"AUTHELIA_WEBAUTHN_DISPLAY_NAME"},{"path":"webauthn.attestation_conveyance_preference","secret":false,"env":"AUTHELIA_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE"},{"path":"webauthn.user_verification","secret":false,"env":"AUTHELIA_WEBAUTHN_USER_VERIFICATION"},{"path":"webauthn.timeout","secret":false,"env":"AUTHELIA_WEBAUTHN_TIMEOUT"},{"path":"password_policy.standard.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_ENABLED"},{"path":"password_policy.standard.min_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MIN_LENGTH"},{"path":"password_policy.standard.max_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MAX_LENGTH"},{"path":"password_policy.standard.require_uppercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_UPPERCASE"},{"path":"password_policy.standard.require_lowercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_LOWERCASE"},{"path":"password_policy.standard.require_number","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_NUMBER"},{"path":"password_policy.standard.require_special","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_SPECIAL"},{"path":"password_policy.zxcvbn.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_ENABLED"},{"path":"password_policy.zxcvbn.min_score","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_MIN_SCORE"},{"path":"privacy_policy.enabled","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_ENABLED"},{"path":"privacy_policy.require_user_acceptance","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_REQUIRE_USER_ACCEPTANCE"},{"path":"privacy_policy.policy_url","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_POLICY_URL"}] \ No newline at end of file +[{"path":"theme","secret":false,"env":"AUTHELIA_THEME"},{"path":"certificates_directory","secret":false,"env":"AUTHELIA_CERTIFICATES_DIRECTORY"},{"path":"jwt_secret","secret":true,"env":"AUTHELIA_JWT_SECRET_FILE"},{"path":"default_redirection_url","secret":false,"env":"AUTHELIA_DEFAULT_REDIRECTION_URL"},{"path":"default_2fa_method","secret":false,"env":"AUTHELIA_DEFAULT_2FA_METHOD"},{"path":"log.level","secret":false,"env":"AUTHELIA_LOG_LEVEL"},{"path":"log.format","secret":false,"env":"AUTHELIA_LOG_FORMAT"},{"path":"log.file_path","secret":false,"env":"AUTHELIA_LOG_FILE_PATH"},{"path":"log.keep_stdout","secret":false,"env":"AUTHELIA_LOG_KEEP_STDOUT"},{"path":"identity_providers.oidc.hmac_secret","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE"},{"path":"identity_providers.oidc.issuer_certificate_chain","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE"},{"path":"identity_providers.oidc.issuer_private_key","secret":true,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE"},{"path":"identity_providers.oidc.access_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ACCESS_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.authorize_code_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_AUTHORIZE_CODE_LIFESPAN"},{"path":"identity_providers.oidc.id_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ID_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.refresh_token_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_REFRESH_TOKEN_LIFESPAN"},{"path":"identity_providers.oidc.enable_client_debug_messages","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_CLIENT_DEBUG_MESSAGES"},{"path":"identity_providers.oidc.minimum_parameter_entropy","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_MINIMUM_PARAMETER_ENTROPY"},{"path":"identity_providers.oidc.enforce_pkce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENFORCE_PKCE"},{"path":"identity_providers.oidc.enable_pkce_plain_challenge","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_ENABLE_PKCE_PLAIN_CHALLENGE"},{"path":"identity_providers.oidc.pushed_authorizations.enforce","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_PUSHED_AUTHORIZATIONS_ENFORCE"},{"path":"identity_providers.oidc.pushed_authorizations.context_lifespan","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_PUSHED_AUTHORIZATIONS_CONTEXT_LIFESPAN"},{"path":"identity_providers.oidc.cors.allowed_origins_from_client_redirect_uris","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC_CORS_ALLOWED_ORIGINS_FROM_CLIENT_REDIRECT_URIS"},{"path":"identity_providers.oidc","secret":false,"env":"AUTHELIA_IDENTITY_PROVIDERS_OIDC"},{"path":"authentication_backend.password_reset.disable","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_DISABLE"},{"path":"authentication_backend.password_reset.custom_url","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_PASSWORD_RESET_CUSTOM_URL"},{"path":"authentication_backend.refresh_interval","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_REFRESH_INTERVAL"},{"path":"authentication_backend.file.path","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PATH"},{"path":"authentication_backend.file.watch","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_WATCH"},{"path":"authentication_backend.file.password.algorithm","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ALGORITHM"},{"path":"authentication_backend.file.password.argon2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_VARIANT"},{"path":"authentication_backend.file.password.argon2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_ITERATIONS"},{"path":"authentication_backend.file.password.argon2.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_MEMORY"},{"path":"authentication_backend.file.password.argon2.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_PARALLELISM"},{"path":"authentication_backend.file.password.argon2.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_KEY_LENGTH"},{"path":"authentication_backend.file.password.argon2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ARGON2_SALT_LENGTH"},{"path":"authentication_backend.file.password.sha2crypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_VARIANT"},{"path":"authentication_backend.file.password.sha2crypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.sha2crypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SHA2CRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.pbkdf2.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_VARIANT"},{"path":"authentication_backend.file.password.pbkdf2.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_ITERATIONS"},{"path":"authentication_backend.file.password.pbkdf2.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PBKDF2_SALT_LENGTH"},{"path":"authentication_backend.file.password.bcrypt.variant","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_VARIANT"},{"path":"authentication_backend.file.password.bcrypt.cost","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_BCRYPT_COST"},{"path":"authentication_backend.file.password.scrypt.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_ITERATIONS"},{"path":"authentication_backend.file.password.scrypt.block_size","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_BLOCK_SIZE"},{"path":"authentication_backend.file.password.scrypt.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_PARALLELISM"},{"path":"authentication_backend.file.password.scrypt.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_KEY_LENGTH"},{"path":"authentication_backend.file.password.scrypt.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SCRYPT_SALT_LENGTH"},{"path":"authentication_backend.file.password.iterations","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_ITERATIONS"},{"path":"authentication_backend.file.password.memory","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_MEMORY"},{"path":"authentication_backend.file.password.parallelism","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_PARALLELISM"},{"path":"authentication_backend.file.password.key_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_KEY_LENGTH"},{"path":"authentication_backend.file.password.salt_length","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_PASSWORD_SALT_LENGTH"},{"path":"authentication_backend.file.search.email","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_EMAIL"},{"path":"authentication_backend.file.search.case_insensitive","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_FILE_SEARCH_CASE_INSENSITIVE"},{"path":"authentication_backend.ldap.address","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDRESS"},{"path":"authentication_backend.ldap.implementation","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_IMPLEMENTATION"},{"path":"authentication_backend.ldap.timeout","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TIMEOUT"},{"path":"authentication_backend.ldap.start_tls","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_START_TLS"},{"path":"authentication_backend.ldap.tls.minimum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MINIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.maximum_version","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_MAXIMUM_VERSION"},{"path":"authentication_backend.ldap.tls.skip_verify","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SKIP_VERIFY"},{"path":"authentication_backend.ldap.tls.server_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_SERVER_NAME"},{"path":"authentication_backend.ldap.tls.private_key","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_PRIVATE_KEY_FILE"},{"path":"authentication_backend.ldap.tls.certificate_chain","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"authentication_backend.ldap.base_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_BASE_DN"},{"path":"authentication_backend.ldap.additional_users_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_USERS_DN"},{"path":"authentication_backend.ldap.users_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USERS_FILTER"},{"path":"authentication_backend.ldap.additional_groups_dn","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ADDITIONAL_GROUPS_DN"},{"path":"authentication_backend.ldap.groups_filter","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUPS_FILTER"},{"path":"authentication_backend.ldap.group_search_mode","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_GROUP_SEARCH_MODE"},{"path":"authentication_backend.ldap.attributes.distinguished_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISTINGUISHED_NAME"},{"path":"authentication_backend.ldap.attributes.username","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_USERNAME"},{"path":"authentication_backend.ldap.attributes.display_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_DISPLAY_NAME"},{"path":"authentication_backend.ldap.attributes.mail","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MAIL"},{"path":"authentication_backend.ldap.attributes.member_of","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_MEMBER_OF"},{"path":"authentication_backend.ldap.attributes.group_name","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_ATTRIBUTES_GROUP_NAME"},{"path":"authentication_backend.ldap.permit_referrals","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_REFERRALS"},{"path":"authentication_backend.ldap.permit_unauthenticated_bind","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_UNAUTHENTICATED_BIND"},{"path":"authentication_backend.ldap.permit_feature_detection_failure","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PERMIT_FEATURE_DETECTION_FAILURE"},{"path":"authentication_backend.ldap.user","secret":false,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_USER"},{"path":"authentication_backend.ldap.password","secret":true,"env":"AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE"},{"path":"session.name","secret":false,"env":"AUTHELIA_SESSION_NAME"},{"path":"session.same_site","secret":false,"env":"AUTHELIA_SESSION_SAME_SITE"},{"path":"session.expiration","secret":false,"env":"AUTHELIA_SESSION_EXPIRATION"},{"path":"session.inactivity","secret":false,"env":"AUTHELIA_SESSION_INACTIVITY"},{"path":"session.remember_me","secret":false,"env":"AUTHELIA_SESSION_REMEMBER_ME"},{"path":"session","secret":false,"env":"AUTHELIA_SESSION"},{"path":"session.secret","secret":true,"env":"AUTHELIA_SESSION_SECRET_FILE"},{"path":"session.redis.host","secret":false,"env":"AUTHELIA_SESSION_REDIS_HOST"},{"path":"session.redis.port","secret":false,"env":"AUTHELIA_SESSION_REDIS_PORT"},{"path":"session.redis.username","secret":false,"env":"AUTHELIA_SESSION_REDIS_USERNAME"},{"path":"session.redis.password","secret":true,"env":"AUTHELIA_SESSION_REDIS_PASSWORD_FILE"},{"path":"session.redis.database_index","secret":false,"env":"AUTHELIA_SESSION_REDIS_DATABASE_INDEX"},{"path":"session.redis.maximum_active_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MAXIMUM_ACTIVE_CONNECTIONS"},{"path":"session.redis.minimum_idle_connections","secret":false,"env":"AUTHELIA_SESSION_REDIS_MINIMUM_IDLE_CONNECTIONS"},{"path":"session.redis.tls.minimum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MINIMUM_VERSION"},{"path":"session.redis.tls.maximum_version","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_MAXIMUM_VERSION"},{"path":"session.redis.tls.skip_verify","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SKIP_VERIFY"},{"path":"session.redis.tls.server_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_TLS_SERVER_NAME"},{"path":"session.redis.tls.private_key","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_PRIVATE_KEY_FILE"},{"path":"session.redis.tls.certificate_chain","secret":true,"env":"AUTHELIA_SESSION_REDIS_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"session.redis.high_availability.sentinel_name","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_NAME"},{"path":"session.redis.high_availability.sentinel_username","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_USERNAME"},{"path":"session.redis.high_availability.sentinel_password","secret":true,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_SENTINEL_PASSWORD_FILE"},{"path":"session.redis.high_availability.route_by_latency","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_BY_LATENCY"},{"path":"session.redis.high_availability.route_randomly","secret":false,"env":"AUTHELIA_SESSION_REDIS_HIGH_AVAILABILITY_ROUTE_RANDOMLY"},{"path":"session.domain","secret":false,"env":"AUTHELIA_SESSION_DOMAIN"},{"path":"totp.disable","secret":false,"env":"AUTHELIA_TOTP_DISABLE"},{"path":"totp.issuer","secret":false,"env":"AUTHELIA_TOTP_ISSUER"},{"path":"totp.algorithm","secret":false,"env":"AUTHELIA_TOTP_ALGORITHM"},{"path":"totp.digits","secret":false,"env":"AUTHELIA_TOTP_DIGITS"},{"path":"totp.period","secret":false,"env":"AUTHELIA_TOTP_PERIOD"},{"path":"totp.skew","secret":false,"env":"AUTHELIA_TOTP_SKEW"},{"path":"totp.secret_size","secret":false,"env":"AUTHELIA_TOTP_SECRET_SIZE"},{"path":"duo_api.disable","secret":false,"env":"AUTHELIA_DUO_API_DISABLE"},{"path":"duo_api.hostname","secret":false,"env":"AUTHELIA_DUO_API_HOSTNAME"},{"path":"duo_api.integration_key","secret":true,"env":"AUTHELIA_DUO_API_INTEGRATION_KEY_FILE"},{"path":"duo_api.secret_key","secret":true,"env":"AUTHELIA_DUO_API_SECRET_KEY_FILE"},{"path":"duo_api.enable_self_enrollment","secret":false,"env":"AUTHELIA_DUO_API_ENABLE_SELF_ENROLLMENT"},{"path":"access_control.default_policy","secret":false,"env":"AUTHELIA_ACCESS_CONTROL_DEFAULT_POLICY"},{"path":"ntp.address","secret":false,"env":"AUTHELIA_NTP_ADDRESS"},{"path":"ntp.version","secret":false,"env":"AUTHELIA_NTP_VERSION"},{"path":"ntp.max_desync","secret":false,"env":"AUTHELIA_NTP_MAX_DESYNC"},{"path":"ntp.disable_startup_check","secret":false,"env":"AUTHELIA_NTP_DISABLE_STARTUP_CHECK"},{"path":"ntp.disable_failure","secret":false,"env":"AUTHELIA_NTP_DISABLE_FAILURE"},{"path":"regulation.max_retries","secret":false,"env":"AUTHELIA_REGULATION_MAX_RETRIES"},{"path":"regulation.find_time","secret":false,"env":"AUTHELIA_REGULATION_FIND_TIME"},{"path":"regulation.ban_time","secret":false,"env":"AUTHELIA_REGULATION_BAN_TIME"},{"path":"storage.local.path","secret":false,"env":"AUTHELIA_STORAGE_LOCAL_PATH"},{"path":"storage.mysql.address","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_ADDRESS"},{"path":"storage.mysql.database","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_DATABASE"},{"path":"storage.mysql.username","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_USERNAME"},{"path":"storage.mysql.password","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE"},{"path":"storage.mysql.timeout","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TIMEOUT"},{"path":"storage.mysql.host","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_HOST"},{"path":"storage.mysql.port","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_PORT"},{"path":"storage.mysql.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MINIMUM_VERSION"},{"path":"storage.mysql.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_MAXIMUM_VERSION"},{"path":"storage.mysql.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SKIP_VERIFY"},{"path":"storage.mysql.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_MYSQL_TLS_SERVER_NAME"},{"path":"storage.mysql.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_TLS_PRIVATE_KEY_FILE"},{"path":"storage.mysql.tls.certificate_chain","secret":true,"env":"AUTHELIA_STORAGE_MYSQL_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"storage.postgres.address","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_ADDRESS"},{"path":"storage.postgres.database","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_DATABASE"},{"path":"storage.postgres.username","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_USERNAME"},{"path":"storage.postgres.password","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE"},{"path":"storage.postgres.timeout","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TIMEOUT"},{"path":"storage.postgres.host","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_HOST"},{"path":"storage.postgres.port","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_PORT"},{"path":"storage.postgres.schema","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SCHEMA"},{"path":"storage.postgres.tls.minimum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MINIMUM_VERSION"},{"path":"storage.postgres.tls.maximum_version","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_MAXIMUM_VERSION"},{"path":"storage.postgres.tls.skip_verify","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SKIP_VERIFY"},{"path":"storage.postgres.tls.server_name","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_SERVER_NAME"},{"path":"storage.postgres.tls.private_key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_PRIVATE_KEY_FILE"},{"path":"storage.postgres.tls.certificate_chain","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"storage.postgres.ssl.mode","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_MODE"},{"path":"storage.postgres.ssl.root_certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_ROOT_CERTIFICATE"},{"path":"storage.postgres.ssl.certificate","secret":false,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_CERTIFICATE"},{"path":"storage.postgres.ssl.key","secret":true,"env":"AUTHELIA_STORAGE_POSTGRES_SSL_KEY_FILE"},{"path":"storage.encryption_key","secret":true,"env":"AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE"},{"path":"notifier.disable_startup_check","secret":false,"env":"AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK"},{"path":"notifier.filesystem.filename","secret":false,"env":"AUTHELIA_NOTIFIER_FILESYSTEM_FILENAME"},{"path":"notifier.smtp.address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_ADDRESS"},{"path":"notifier.smtp.timeout","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TIMEOUT"},{"path":"notifier.smtp.username","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_USERNAME"},{"path":"notifier.smtp.password","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE"},{"path":"notifier.smtp.identifier","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_IDENTIFIER"},{"path":"notifier.smtp.sender","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SENDER"},{"path":"notifier.smtp.subject","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_SUBJECT"},{"path":"notifier.smtp.startup_check_address","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_STARTUP_CHECK_ADDRESS"},{"path":"notifier.smtp.disable_require_tls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_REQUIRE_TLS"},{"path":"notifier.smtp.disable_html_emails","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_HTML_EMAILS"},{"path":"notifier.smtp.disable_starttls","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_DISABLE_STARTTLS"},{"path":"notifier.smtp.tls.minimum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MINIMUM_VERSION"},{"path":"notifier.smtp.tls.maximum_version","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_MAXIMUM_VERSION"},{"path":"notifier.smtp.tls.skip_verify","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SKIP_VERIFY"},{"path":"notifier.smtp.tls.server_name","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_SERVER_NAME"},{"path":"notifier.smtp.tls.private_key","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_PRIVATE_KEY_FILE"},{"path":"notifier.smtp.tls.certificate_chain","secret":true,"env":"AUTHELIA_NOTIFIER_SMTP_TLS_CERTIFICATE_CHAIN_FILE"},{"path":"notifier.smtp.host","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_HOST"},{"path":"notifier.smtp.port","secret":false,"env":"AUTHELIA_NOTIFIER_SMTP_PORT"},{"path":"notifier.template_path","secret":false,"env":"AUTHELIA_NOTIFIER_TEMPLATE_PATH"},{"path":"server.address","secret":false,"env":"AUTHELIA_SERVER_ADDRESS"},{"path":"server.asset_path","secret":false,"env":"AUTHELIA_SERVER_ASSET_PATH"},{"path":"server.disable_healthcheck","secret":false,"env":"AUTHELIA_SERVER_DISABLE_HEALTHCHECK"},{"path":"server.tls.certificate","secret":false,"env":"AUTHELIA_SERVER_TLS_CERTIFICATE"},{"path":"server.tls.key","secret":true,"env":"AUTHELIA_SERVER_TLS_KEY_FILE"},{"path":"server.headers.csp_template","secret":false,"env":"AUTHELIA_SERVER_HEADERS_CSP_TEMPLATE"},{"path":"server.endpoints.enable_pprof","secret":false,"env":"AUTHELIA_SERVER_ENDPOINTS_ENABLE_PPROF"},{"path":"server.endpoints.enable_expvars","secret":false,"env":"AUTHELIA_SERVER_ENDPOINTS_ENABLE_EXPVARS"},{"path":"server.buffers.read","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_READ"},{"path":"server.buffers.write","secret":false,"env":"AUTHELIA_SERVER_BUFFERS_WRITE"},{"path":"server.timeouts.read","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_READ"},{"path":"server.timeouts.write","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_WRITE"},{"path":"server.timeouts.idle","secret":false,"env":"AUTHELIA_SERVER_TIMEOUTS_IDLE"},{"path":"server.host","secret":false,"env":"AUTHELIA_SERVER_HOST"},{"path":"server.port","secret":false,"env":"AUTHELIA_SERVER_PORT"},{"path":"server.path","secret":false,"env":"AUTHELIA_SERVER_PATH"},{"path":"telemetry.metrics.enabled","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ENABLED"},{"path":"telemetry.metrics.address","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_ADDRESS"},{"path":"telemetry.metrics.buffers.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_READ"},{"path":"telemetry.metrics.buffers.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_BUFFERS_WRITE"},{"path":"telemetry.metrics.timeouts.read","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_READ"},{"path":"telemetry.metrics.timeouts.write","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_WRITE"},{"path":"telemetry.metrics.timeouts.idle","secret":false,"env":"AUTHELIA_TELEMETRY_METRICS_TIMEOUTS_IDLE"},{"path":"webauthn.disable","secret":false,"env":"AUTHELIA_WEBAUTHN_DISABLE"},{"path":"webauthn.display_name","secret":false,"env":"AUTHELIA_WEBAUTHN_DISPLAY_NAME"},{"path":"webauthn.attestation_conveyance_preference","secret":false,"env":"AUTHELIA_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE"},{"path":"webauthn.user_verification","secret":false,"env":"AUTHELIA_WEBAUTHN_USER_VERIFICATION"},{"path":"webauthn.timeout","secret":false,"env":"AUTHELIA_WEBAUTHN_TIMEOUT"},{"path":"password_policy.standard.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_ENABLED"},{"path":"password_policy.standard.min_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MIN_LENGTH"},{"path":"password_policy.standard.max_length","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_MAX_LENGTH"},{"path":"password_policy.standard.require_uppercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_UPPERCASE"},{"path":"password_policy.standard.require_lowercase","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_LOWERCASE"},{"path":"password_policy.standard.require_number","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_NUMBER"},{"path":"password_policy.standard.require_special","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_STANDARD_REQUIRE_SPECIAL"},{"path":"password_policy.zxcvbn.enabled","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_ENABLED"},{"path":"password_policy.zxcvbn.min_score","secret":false,"env":"AUTHELIA_PASSWORD_POLICY_ZXCVBN_MIN_SCORE"},{"path":"privacy_policy.enabled","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_ENABLED"},{"path":"privacy_policy.require_user_acceptance","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_REQUIRE_USER_ACCEPTANCE"},{"path":"privacy_policy.policy_url","secret":false,"env":"AUTHELIA_PRIVACY_POLICY_POLICY_URL"}] \ No newline at end of file diff --git a/docs/static/schemas/latest/configuration.json b/docs/static/schemas/latest/configuration.json new file mode 100644 index 000000000..e74be8b58 --- /dev/null +++ b/docs/static/schemas/latest/configuration.json @@ -0,0 +1,2866 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.authelia.com/v4.38/json-schema/configuration.json", + "$ref": "#/$defs/Configuration", + "$defs": { + "AccessControl": { + "properties": { + "default_policy": { + "type": "string", + "enum": [ + "deny", + "one_factor", + "two_factor" + ], + "title": "Default Authorization Policy", + "description": "The default policy applied to all authorization requests. Not relevant to OpenID Connect.", + "default": "deny" + }, + "networks": { + "items": { + "$ref": "#/$defs/AccessControlNetwork" + }, + "type": "array", + "title": "Named Networks", + "description": "The list of named networks which can be reused in any ACL rule" + }, + "rules": { + "items": { + "$ref": "#/$defs/AccessControlRule" + }, + "type": "array", + "title": "Rules List", + "description": "The list of ACL rules to enumerate for requests" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AccessControl represents the configuration related to ACLs." + }, + "AccessControlNetwork": { + "properties": { + "name": { + "type": "string", + "title": "Network Name", + "description": "The name of this network to be used in the networks section of the rules section" + }, + "networks": { + "$ref": "#/$defs/AccessControlNetworkNetworks", + "title": "Networks", + "description": "The remote IP's or network ranges in CIDR notation that this rule applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "networks" + ], + "description": "AccessControlNetwork represents one ACL network group entry." + }, + "AccessControlNetworkNetworks": { + "oneOf": [ + { + "type": "string", + "pattern": "((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\\/([0-2]?[0-9]|3[0-2]))?$)|(^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))?(\\/(12[0-8]|1[0-1][0-9]|[0-9]{1,2}))?$))" + }, + { + "items": { + "type": "string", + "pattern": "((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\\/([0-2]?[0-9]|3[0-2]))?$)|(^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))?(\\/(12[0-8]|1[0-1][0-9]|[0-9]{1,2}))?$))" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRule": { + "oneOf": [ + { + "required": [ + "domain" + ], + "title": "Domain" + }, + { + "required": [ + "domain_regex" + ], + "title": "Domain Regex" + } + ], + "properties": { + "domain": { + "$ref": "#/$defs/AccessControlRuleDomains", + "title": "Domain Literals", + "description": "The literal domains to match the domain against that this rule applies to" + }, + "domain_regex": { + "$ref": "#/$defs/AccessControlRuleRegex", + "title": "Domain Regex Patterns", + "description": "The regex patterns to match the domain against that this rule applies to" + }, + "policy": { + "type": "string", + "enum": [ + "bypass", + "deny", + "one_factor", + "two_factor" + ], + "title": "Rule Policy", + "description": "The policy this rule applies when all criteria match" + }, + "subject": { + "$ref": "#/$defs/AccessControlRuleSubjects", + "title": "AccessControlRuleSubjects", + "description": "The users or groups that this rule applies to" + }, + "networks": { + "$ref": "#/$defs/AccessControlRuleNetworks", + "title": "Networks", + "description": "The remote IP's, network ranges in CIDR notation, or network names that this rule applies to" + }, + "resources": { + "$ref": "#/$defs/AccessControlRuleRegex", + "title": "Resources or Paths", + "description": "The regex patterns to match the resource paths that this rule applies to" + }, + "methods": { + "$ref": "#/$defs/AccessControlRuleMethods", + "description": "The list of request methods this rule applies to" + }, + "query": { + "items": { + "items": { + "$ref": "#/$defs/AccessControlRuleQuery" + }, + "type": "array" + }, + "type": "array", + "title": "Query Rules", + "description": "The list of query parameter rules this rule applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "policy" + ], + "description": "AccessControlRule represents one ACL rule entry." + }, + "AccessControlRuleDomains": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleMethods": { + "oneOf": [ + { + "type": "string", + "enum": [ + "GET", + "HEAD", + "POST", + "PUT", + "PATCH", + "DELETE", + "TRACE", + "CONNECT", + "OPTIONS", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK" + ] + }, + { + "items": { + "type": "string", + "enum": [ + "GET", + "HEAD", + "POST", + "PUT", + "PATCH", + "DELETE", + "TRACE", + "CONNECT", + "OPTIONS", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK" + ] + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleNetworks": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleQuery": { + "properties": { + "operator": { + "type": "string", + "enum": [ + "equal", + "not equal", + "present", + "absent", + "pattern", + "not pattern" + ], + "title": "Operator", + "description": "The list of query parameter rules this rule applies to" + }, + "key": { + "type": "string", + "title": "Key", + "description": "The Query Parameter key this rule applies to" + }, + "value": { + "title": "Value", + "description": "The Query Parameter value for this rule" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "key" + ], + "description": "AccessControlRuleQuery represents the ACL query criteria." + }, + "AccessControlRuleRegex": { + "oneOf": [ + { + "type": "string", + "format": "regex" + }, + { + "items": { + "type": "string", + "format": "regex" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleSubjects": { + "oneOf": [ + { + "type": "string", + "pattern": "^(user|group):.+$" + }, + { + "items": { + "type": "string", + "pattern": "^(user|group):.+$" + }, + "type": "array" + }, + { + "items": { + "items": { + "type": "string", + "pattern": "^(user|group):.+$" + }, + "type": "array" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AddressLDAP": { + "type": "string", + "pattern": "^((ldaps?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)?|ldapi:\\/\\/(\\/[^?\\n]+)?)$", + "format": "uri" + }, + "AddressSMTP": { + "type": "string", + "pattern": "^((smtp|submissions?):\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)?$", + "format": "uri" + }, + "AddressTCP": { + "type": "string", + "pattern": "^((tcp(4|6)?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)(\\/.*)?|unix:\\/\\/\\/[^?\\n]+(\\?umask=[0-7]{3,4})?)$", + "format": "uri" + }, + "AddressUDP": { + "type": "string", + "pattern": "^(udp(4|6)?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)(\\/.*)?$", + "format": "uri" + }, + "AuthenticationBackend": { + "properties": { + "password_reset": { + "$ref": "#/$defs/AuthenticationBackendPasswordReset", + "title": "Password Reset", + "description": "Allows configuration of the password reset behaviour" + }, + "refresh_interval": { + "type": "string", + "title": "Refresh Interval", + "description": "How frequently the user details are refreshed from the backend" + }, + "file": { + "$ref": "#/$defs/AuthenticationBackendFile", + "title": "File Backend", + "description": "The file authentication backend configuration" + }, + "ldap": { + "$ref": "#/$defs/AuthenticationBackendLDAP", + "title": "LDAP Backend", + "description": "The LDAP authentication backend configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackend represents the configuration related to the authentication backend." + }, + "AuthenticationBackendFile": { + "properties": { + "path": { + "type": "string", + "title": "Path", + "description": "The file path to the user database" + }, + "watch": { + "type": "boolean", + "title": "Watch", + "description": "Enables watching the file for external changes and dynamically reloading the database", + "default": false + }, + "password": { + "$ref": "#/$defs/AuthenticationBackendFilePassword", + "title": "Password Options", + "description": "Allows configuration of the password hashing options when the user passwords are changed directly by Authelia" + }, + "search": { + "$ref": "#/$defs/AuthenticationBackendFileSearch", + "title": "Search", + "description": "Configures the user searching behaviour" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFile represents the configuration related to file-based backend." + }, + "AuthenticationBackendFilePassword": { + "properties": { + "algorithm": { + "type": "string", + "enum": [ + "argon2", + "sha2crypt", + "pbkdf2", + "bcrypt", + "scrypt" + ], + "title": "Algorithm", + "description": "The password hashing algorithm to use", + "default": "argon2" + }, + "argon2": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordArgon2", + "title": "Argon2", + "description": "Configure the Argon2 password hashing parameters" + }, + "sha2crypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordSHA2Crypt", + "title": "SHA2Crypt", + "description": "Configure the SHA2Crypt password hashing parameters" + }, + "pbkdf2": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordPBKDF2", + "title": "PBKDF2", + "description": "Configure the PBKDF2 password hashing parameters" + }, + "bcrypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordBCrypt", + "title": "BCrypt", + "description": "Configure the BCrypt password hashing parameters" + }, + "scrypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordSCrypt", + "title": "SCrypt", + "description": "Configure the SCrypt password hashing parameters" + }, + "iterations": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "memory": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "parallelism": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "key_length": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "salt_length": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePassword represents the configuration related to password hashing." + }, + "AuthenticationBackendFilePasswordArgon2": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "argon2id", + "argon2i", + "argon2d" + ], + "title": "Variant", + "description": "The Argon2 variant to be used", + "default": "argon2id" + }, + "iterations": { + "type": "integer", + "title": "Iterations", + "description": "The number of Argon2 iterations (parameter t) to be used", + "default": 3 + }, + "memory": { + "type": "integer", + "maximum": 4294967295, + "minimum": 8, + "title": "Memory", + "description": "The Argon2 amount of memory in kibibytes (parameter m) to be used", + "default": 65536 + }, + "parallelism": { + "type": "integer", + "maximum": 16777215, + "minimum": 1, + "title": "Parallelism", + "description": "The Argon2 degree of parallelism (parameter p) to be used", + "default": 4 + }, + "key_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 4, + "title": "Key Length", + "description": "The Argon2 key output length", + "default": 32 + }, + "salt_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 1, + "title": "Salt Length", + "description": "The Argon2 salt length", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordArgon2 represents the argon2 hashing settings." + }, + "AuthenticationBackendFilePasswordBCrypt": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "standard", + "sha256" + ], + "title": "Variant", + "description": "The BCrypt variant to be used", + "default": "standard" + }, + "cost": { + "type": "integer", + "maximum": 31, + "minimum": 10, + "title": "Cost", + "description": "The BCrypt cost to be used", + "default": 12 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordBCrypt represents the bcrypt hashing settings." + }, + "AuthenticationBackendFilePasswordPBKDF2": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "title": "Variant", + "description": "The PBKDF2 variant to be used", + "default": "sha512" + }, + "iterations": { + "type": "integer", + "maximum": 2147483647, + "minimum": 100000, + "title": "Iterations", + "description": "The PBKDF2 iterations to be used", + "default": 310000 + }, + "salt_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 8, + "title": "Salt Length", + "description": "The PBKDF2 salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordPBKDF2 represents the PBKDF2 hashing settings." + }, + "AuthenticationBackendFilePasswordSCrypt": { + "properties": { + "iterations": { + "type": "integer", + "maximum": 58, + "minimum": 1, + "title": "Iterations", + "description": "The SCrypt iterations to be used", + "default": 16 + }, + "block_size": { + "type": "integer", + "maximum": 36028797018963967, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt block size to be used", + "default": 8 + }, + "parallelism": { + "type": "integer", + "maximum": 1073741823, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt parallelism factor to be used", + "default": 1 + }, + "key_length": { + "type": "integer", + "maximum": 137438953440, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt key length to be used", + "default": 32 + }, + "salt_length": { + "type": "integer", + "maximum": 1024, + "minimum": 8, + "title": "Salt Length", + "description": "The SCrypt salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordSCrypt represents the scrypt hashing settings." + }, + "AuthenticationBackendFilePasswordSHA2Crypt": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "sha256", + "sha512" + ], + "title": "Variant", + "description": "The SHA2Crypt variant to be used", + "default": "sha512" + }, + "iterations": { + "type": "integer", + "maximum": 999999999, + "minimum": 1000, + "title": "Iterations", + "description": "The SHA2Crypt iterations (parameter rounds) to be used", + "default": 50000 + }, + "salt_length": { + "type": "integer", + "maximum": 16, + "minimum": 1, + "title": "Salt Length", + "description": "The SHA2Crypt salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordSHA2Crypt represents the sha2crypt hashing settings." + }, + "AuthenticationBackendFileSearch": { + "properties": { + "email": { + "type": "boolean", + "title": "Email Searching", + "description": "Allows users to either use their username or their configured email as a username", + "default": false + }, + "case_insensitive": { + "type": "boolean", + "title": "Case Insensitive Searching", + "description": "Allows usernames to be any case during the search", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFileSearch represents the configuration related to file-based backend searching." + }, + "AuthenticationBackendLDAP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressLDAP", + "title": "Address", + "description": "The address of the LDAP directory server" + }, + "implementation": { + "type": "string", + "enum": [ + "custom", + "activedirectory", + "rfc2307bis", + "freeipa", + "lldap", + "glauth" + ], + "title": "Implementation", + "description": "The implementation which mostly decides the default values", + "default": "custom" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The LDAP directory server connection timeout" + }, + "start_tls": { + "type": "boolean", + "title": "StartTLS", + "description": "Enables the use of StartTLS", + "default": false + }, + "tls": { + "$ref": "#/$defs/TLS", + "title": "TLS", + "description": "The LDAP directory server TLS connection properties" + }, + "base_dn": { + "type": "string", + "title": "Base DN", + "description": "The base for all directory server operations" + }, + "additional_users_dn": { + "type": "string", + "title": "Additional User Base", + "description": "The base in addition to the Base DN for all directory server operations for users" + }, + "users_filter": { + "type": "string", + "title": "Users Filter", + "description": "The LDAP filter used to search for user objects" + }, + "additional_groups_dn": { + "type": "string", + "title": "Additional Group Base", + "description": "The base in addition to the Base DN for all directory server operations for groups" + }, + "groups_filter": { + "type": "string", + "title": "Groups Filter", + "description": "The LDAP filter used to search for group objects" + }, + "GroupSearchMode": { + "type": "string" + }, + "attributes": { + "$ref": "#/$defs/AuthenticationBackendLDAPAttributes" + }, + "permit_referrals": { + "type": "boolean", + "title": "Permit Referrals", + "description": "Enables chasing LDAP referrals", + "default": false + }, + "permit_unauthenticated_bind": { + "type": "boolean", + "title": "Permit Unauthenticated Bind", + "description": "Enables omission of the password to perform an unauthenticated bind", + "default": false + }, + "permit_feature_detection_failure": { + "type": "boolean", + "title": "Permit Feature Detection Failure", + "description": "Enables failures when detecting directory server features using the Root DSE lookup", + "default": false + }, + "user": { + "type": "string", + "title": "User", + "description": "The user distinguished name for LDAP binding" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password for LDAP authenticated binding" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendLDAP represents the configuration related to LDAP server." + }, + "AuthenticationBackendLDAPAttributes": { + "properties": { + "distinguished_name": { + "type": "string", + "title": "Attribute: Distinguished Name", + "description": "The directory server attribute which contains the distinguished name for all objects" + }, + "username": { + "type": "string", + "title": "Attribute: User Username", + "description": "The directory server attribute which contains the username for all users" + }, + "display_name": { + "type": "string", + "title": "Attribute: User Display Name", + "description": "The directory server attribute which contains the display name for all users" + }, + "mail": { + "type": "string", + "title": "Attribute: User Mail", + "description": "The directory server attribute which contains the mail address for all users and groups" + }, + "MemberOf": { + "type": "string", + "title": "Attribute: Member Of", + "description": "The directory server attribute which contains the objects that an object is a member of" + }, + "group_name": { + "type": "string", + "title": "Attribute: Group Name", + "description": "The directory server attribute which contains the group name for all groups" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendLDAPAttributes represents the configuration related to LDAP server attributes." + }, + "AuthenticationBackendPasswordReset": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the Password Reset option", + "default": false + }, + "custom_url": { + "type": "string", + "format": "uri", + "description": "Disables the internal Password Reset option and instead redirects users to this specified URL" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendPasswordReset represents the configuration related to password reset functionality." + }, + "Configuration": { + "properties": { + "theme": { + "type": "string", + "enum": [ + "auto", + "light", + "dark", + "grey" + ], + "title": "Theme Name", + "description": "The name of the theme to apply to the web UI", + "default": "light" + }, + "certificates_directory": { + "type": "string", + "title": "Certificates Directory Path", + "description": "The path to a directory which is used to determine the certificates that are trusted" + }, + "jwt_secret": { + "type": "string", + "title": "Secret Key for JWT's", + "description": "Used for signing HS256 JWT's for identity verification" + }, + "default_redirection_url": { + "type": "string", + "title": "The default redirection URL", + "description": "Used to redirect users when they visit the portal directly" + }, + "default_2fa_method": { + "type": "string", + "enum": [ + "totp", + "webauthn", + "mobile_push" + ], + "title": "Default 2FA method", + "description": "When a user logs in for the first time this is the 2FA method configured for them" + }, + "log": { + "$ref": "#/$defs/Log", + "title": "Log", + "description": "Logging Configuration" + }, + "identity_providers": { + "$ref": "#/$defs/IdentityProviders", + "title": "Identity Providers", + "description": "Identity Providers Configuration" + }, + "authentication_backend": { + "$ref": "#/$defs/AuthenticationBackend", + "title": "Authentication Backend", + "description": "Authentication Backend Configuration" + }, + "session": { + "$ref": "#/$defs/Session", + "title": "Session", + "description": "Session Configuration" + }, + "totp": { + "$ref": "#/$defs/TOTP", + "title": "TOTP", + "description": "Time-based One Time Password Configuration" + }, + "duo_api": { + "$ref": "#/$defs/DuoAPI", + "title": "Duo API", + "description": "Duo API Configuration" + }, + "access_control": { + "$ref": "#/$defs/AccessControl", + "title": "Access Control", + "description": "Access Control Configuration" + }, + "ntp": { + "$ref": "#/$defs/NTP", + "title": "NTP", + "description": "Network Time Protocol Configuration" + }, + "regulation": { + "$ref": "#/$defs/Regulation", + "title": "Regulation", + "description": "Regulation Configuration" + }, + "storage": { + "$ref": "#/$defs/Storage", + "title": "Storage", + "description": "Storage Configuration" + }, + "notifier": { + "$ref": "#/$defs/Notifier", + "title": "Notifier", + "description": "Notifier Configuration" + }, + "server": { + "$ref": "#/$defs/Server", + "title": "Server", + "description": "Server Configuration" + }, + "telemetry": { + "$ref": "#/$defs/Telemetry", + "title": "Telemetry", + "description": "Telemetry Configuration" + }, + "webauthn": { + "$ref": "#/$defs/WebAuthn", + "title": "WebAuthn", + "description": "WebAuthn Configuration" + }, + "password_policy": { + "$ref": "#/$defs/PasswordPolicy", + "title": "Password Policy", + "description": "Password Policy Configuration" + }, + "privacy_policy": { + "$ref": "#/$defs/PrivacyPolicy", + "title": "Privacy Policy", + "description": "Privacy Policy Configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Configuration object extracted from YAML configuration file." + }, + "DuoAPI": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disable the Duo API integration", + "default": false + }, + "hostname": { + "type": "string", + "format": "hostname", + "title": "Hostname", + "description": "The Hostname provided by your Duo API dashboard" + }, + "integration_key": { + "type": "string", + "title": "Integration Key", + "description": "The Integration Key provided by your Duo API dashboard" + }, + "secret_key": { + "type": "string", + "title": "Secret Key", + "description": "The Secret Key provided by your Duo API dashboard" + }, + "enable_self_enrollment": { + "type": "boolean", + "title": "Enable Self Enrollment", + "description": "Enable the Self Enrollment flow", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "DuoAPI represents the configuration related to Duo API." + }, + "IdentityProviders": { + "properties": { + "oidc": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnect" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProviders represents the Identity Providers configuration for Authelia." + }, + "IdentityProvidersOpenIDConnect": { + "properties": { + "hmac_secret": { + "type": "string", + "title": "HMAC Secret", + "description": "The HMAC Secret used to sign Access Tokens" + }, + "issuer_private_keys": { + "items": { + "$ref": "#/$defs/JWK" + }, + "type": "array", + "title": "Issuer Private Keys", + "description": "The Private Keys used to sign ID Tokens" + }, + "issuer_certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Issuer Certificate Chain", + "description": "The Issuer Certificate Chain with an RSA Public Key used to sign ID Tokens" + }, + "issuer_private_key": { + "type": "string", + "title": "Issuer Private Key", + "description": "The Issuer Private Key with an RSA Private Key used to sign ID Tokens" + }, + "access_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Access Token Lifespan", + "description": "The duration an Access Token is valid for" + }, + "authorize_code_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Authorize Code Lifespan", + "description": "The duration an Authorization Code is valid for" + }, + "id_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "ID Token Lifespan", + "description": "The duration an ID Token is valid for" + }, + "refresh_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Refresh Token Lifespan", + "description": "The duration a Refresh Token is valid for" + }, + "enable_client_debug_messages": { + "type": "boolean", + "title": "Enable Client Debug Messages", + "description": "Enables additional debug messages for clients", + "default": false + }, + "minimum_parameter_entropy": { + "type": "integer", + "minimum": -1, + "title": "Minimum Parameter Entropy", + "description": "The minimum entropy of the nonce parameter", + "default": 8 + }, + "enforce_pkce": { + "type": "string", + "enum": [ + "public_clients_only", + "never", + "always" + ], + "title": "Enforce PKCE", + "description": "Controls enforcement of the use of Proof Key for Code Exchange on all clients", + "default": "public_clients_only" + }, + "enable_pkce_plain_challenge": { + "type": "boolean", + "title": "Enable PKCE Plain Challenge", + "description": "Enables use of the discouraged plain Proof Key for Code Exchange challenges", + "default": false + }, + "pushed_authorizations": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectPAR", + "title": "Pushed Authorizations", + "description": "Configuration options for Pushed Authorization Requests" + }, + "cors": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectCORS", + "title": "CORS", + "description": "Configuration options for Cross-Origin Request Sharing" + }, + "clients": { + "items": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClient" + }, + "type": "array", + "title": "Clients", + "description": "OpenID Connect 1.0 clients registry" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnect represents the configuration for OpenID Connect 1.0." + }, + "IdentityProvidersOpenIDConnectCORS": { + "properties": { + "endpoints": { + "items": { + "type": "string", + "enum": [ + "authorization", + "pushed-authorization-request", + "token", + "introspection", + "revocation", + "userinfo" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Endpoints", + "description": "List of endpoints to enable CORS handling for" + }, + "allowed_origins": { + "items": { + "type": "string", + "format": "uri" + }, + "type": "array", + "title": "Allowed Origins", + "description": "List of arbitrary allowed origins for CORS requests" + }, + "allowed_origins_from_client_redirect_uris": { + "type": "boolean", + "title": "Allowed Origins From Client Redirect URIs", + "description": "Automatically include the redirect URIs from the registered clients", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectCORS represents an OpenID Connect 1.0 CORS config." + }, + "IdentityProvidersOpenIDConnectClient": { + "properties": { + "id": { + "type": "string", + "minLength": 1, + "title": "ID", + "description": "The Client ID" + }, + "description": { + "type": "string", + "title": "Description", + "description": "The Client Description for End-Users" + }, + "secret": { + "$ref": "#/$defs/PasswordDigest", + "title": "Secret", + "description": "The Client Secret for Client Authentication" + }, + "sector_identifier": { + "type": "string", + "format": "uri", + "title": "Sector Identifier", + "description": "The Client Sector Identifier for Privacy Isolation" + }, + "public": { + "type": "boolean", + "title": "Public", + "description": "Enables the Public Client Type", + "default": false + }, + "redirect_uris": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClientRedirectURIs", + "title": "Redirect URIs", + "description": "List of authorized redirect URIs" + }, + "audience": { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true, + "title": "Audience", + "description": "List of authorized audiences" + }, + "scopes": { + "items": { + "type": "string", + "enum": [ + "openid", + "offline_access", + "groups", + "email", + "profile" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Scopes", + "description": "The Scopes this client is allowed request and be granted" + }, + "grant_types": { + "items": { + "type": "string", + "enum": [ + "authorization_code", + "implicit", + "refresh_token" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Grant Types", + "description": "The Grant Types this client is allowed to use for the protected endpoints" + }, + "response_types": { + "items": { + "type": "string", + "enum": [ + "code", + "id_token token", + "id_token", + "token", + "code token", + "code id_token", + "code id_token token" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Response Types", + "description": "The Response Types the client is authorized to request" + }, + "response_modes": { + "items": { + "type": "string", + "enum": [ + "form_post", + "query", + "fragment" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Response Modes", + "description": "The Response Modes this client is authorized request" + }, + "authorization_policy": { + "type": "string", + "title": "Authorization Policy", + "description": "The Authorization Policy to apply to this client" + }, + "consent_mode": { + "type": "string", + "enum": [ + "auto", + "explicit", + "implicit", + "pre-configured" + ], + "title": "Consent Mode", + "description": "The Consent Mode used for this client" + }, + "pre_configured_consent_duration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Pre-Configured Consent Duration", + "description": "The Pre-Configured Consent Duration when using Consent Mode pre-configured for this client" + }, + "enforce_par": { + "type": "boolean", + "title": "Enforce PAR", + "description": "Enforces Pushed Authorization Requests for this client", + "default": false + }, + "enforce_pkce": { + "type": "boolean", + "title": "Enforce PKCE", + "description": "Enforces Proof Key for Code Exchange for this client", + "default": false + }, + "pkce_challenge_method": { + "type": "string", + "enum": [ + "plain", + "S256" + ], + "title": "PKCE Challenge Method", + "description": "The PKCE Challenge Method enforced on this client" + }, + "id_token_signing_alg": { + "type": "string", + "enum": [ + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "ID Token Signing Algorithm", + "description": "The algorithm (JWA) this client uses to sign ID Tokens" + }, + "id_token_signing_key_id": { + "type": "string", + "title": "ID Token Signing Key ID", + "description": "The Key ID this client uses to sign ID Tokens (overrides the 'id_token_signing_alg')" + }, + "userinfo_signing_alg": { + "type": "string", + "enum": [ + "none", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Userinfo Signing Algorithm", + "description": "The Userinfo Endpoint Signing Algorithm this client uses" + }, + "userinfo_signing_key_id": { + "type": "string", + "title": "Userinfo Signing Key ID", + "description": "The Key ID this client uses to sign the userinfo responses (overrides the 'userinfo_token_signing_alg')" + }, + "request_object_signing_alg": { + "type": "string", + "enum": [ + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Request Object Signing Algorithm", + "description": "The Request Object Signing Algorithm the provider accepts for this client" + }, + "token_endpoint_auth_signing_alg": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Token Endpoint Auth Signing Algorithm", + "description": "The Token Endpoint Auth Signing Algorithm the provider accepts for this client" + }, + "token_endpoint_auth_method": { + "type": "string", + "enum": [ + "none", + "client_secret_post", + "client_secret_basic", + "private_key_jwt", + "client_secret_jwt" + ], + "title": "Token Endpoint Auth Method", + "description": "The Token Endpoint Auth Method enforced by the provider for this client" + }, + "public_keys": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClientPublicKeys", + "title": "Public Keys", + "description": "Public Key options used to validate request objects and the 'private_key_jwt' client authentication method for this client" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "redirect_uris", + "scopes" + ], + "description": "IdentityProvidersOpenIDConnectClient represents a configuration for an OpenID Connect 1.0 client." + }, + "IdentityProvidersOpenIDConnectClientPublicKeys": { + "oneOf": [ + { + "required": [ + "uri" + ], + "title": "URI" + }, + { + "required": [ + "values" + ], + "title": "Values" + } + ], + "properties": { + "uri": { + "type": "string", + "format": "uri", + "title": "URI", + "description": "URI of the JWKS endpoint which contains the Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client" + }, + "values": { + "items": { + "$ref": "#/$defs/JWK" + }, + "type": "array", + "title": "Values", + "description": "List of arbitrary Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectClientPublicKeys represents the Client Public Keys configuration for an OpenID Connect 1.0 client." + }, + "IdentityProvidersOpenIDConnectClientRedirectURIs": { + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "items": { + "type": "string", + "format": "uri" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "IdentityProvidersOpenIDConnectPAR": { + "properties": { + "enforce": { + "type": "boolean", + "title": "Enforce", + "description": "Enforce the use of PAR for all requests on all clients", + "default": false + }, + "context_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Context Lifespan", + "description": "How long a PAR context is valid for" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectPAR represents an OpenID Connect 1.0 PAR config." + }, + "JWK": { + "properties": { + "key_id": { + "type": "string", + "maxLength": 100, + "title": "Key ID", + "description": "The ID of this JWK" + }, + "use": { + "type": "string", + "enum": [ + "sig" + ], + "title": "Use", + "description": "The Use of this JWK", + "default": "sig" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Algorithm", + "description": "The Algorithm of this JWK" + }, + "key": { + "type": "string", + "description": "The Private/Public key material of this JWK in Base64 PEM format" + }, + "certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Certificate Chain", + "description": "The optional associated certificate which matches the Key public key portion for this JWK" + } + }, + "additionalProperties": false, + "type": "object", + "description": "JWK represents a JWK." + }, + "Log": { + "properties": { + "level": { + "type": "string", + "enum": [ + "error", + "warn", + "info", + "debug", + "trace" + ], + "title": "Level", + "description": "The minimum Level a Log message must be before it's added to the log'" + }, + "format": { + "type": "string", + "enum": [ + "json", + "text" + ], + "title": "Format", + "description": "The Format of Log messages" + }, + "file_path": { + "type": "string", + "title": "File Path", + "description": "The File Path to save the logs to instead of sending them to stdout" + }, + "keep_stdout": { + "type": "boolean", + "title": "Keep Stdout", + "description": "Enables keeping stdout when using the File Path option", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "Log represents the logging configuration." + }, + "NTP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressUDP" + }, + "version": { + "type": "integer", + "enum": [ + 3, + 4 + ], + "title": "NTP Version", + "description": "The NTP Version to use" + }, + "max_desync": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Maximum Desync", + "description": "The maximum amount of time that the server can be out of sync" + }, + "disable_startup_check": { + "type": "boolean", + "title": "Disable Startup Check", + "description": "Disables the NTP Startup Check entirely", + "default": false + }, + "disable_failure": { + "type": "boolean", + "title": "Disable Failure", + "description": "Disables complete failure whe the Startup Check fails and instead just logs the error", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "NTP represents the configuration related to ntp server." + }, + "Notifier": { + "properties": { + "disable_startup_check": { + "type": "boolean", + "title": "Disable Startup Check", + "description": "Disables the notifier startup checks", + "default": false + }, + "filesystem": { + "$ref": "#/$defs/NotifierFileSystem", + "title": "File System", + "description": "The File System notifier" + }, + "smtp": { + "$ref": "#/$defs/NotifierSMTP", + "title": "SMTP", + "description": "The SMTP notifier" + }, + "template_path": { + "type": "string", + "title": "Template Path", + "description": "The path for notifier template overrides" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Notifier represents the configuration of the notifier to use when sending notifications to users." + }, + "NotifierFileSystem": { + "properties": { + "filename": { + "type": "string", + "title": "Filename", + "description": "The file path of the notifications" + } + }, + "additionalProperties": false, + "type": "object", + "description": "NotifierFileSystem represents the configuration of the notifier writing emails in a file." + }, + "NotifierSMTP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressSMTP", + "title": "Address", + "description": "The SMTP server address" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The SMTP server connection timeout" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username for SMTP authentication" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password for SMTP authentication" + }, + "identifier": { + "type": "string", + "title": "Identifier", + "description": "The identifier used during the HELO/EHLO command", + "default": "localhost" + }, + "sender": { + "oneOf": [ + { + "type": "string", + "pattern": "^[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$" + }, + { + "type": "string", + "pattern": "^[^\u003c]+ \u003c[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*\u003e$" + } + ], + "title": "Sender", + "description": "The sender used for SMTP" + }, + "subject": { + "type": "string", + "title": "Subject", + "description": "The subject format used", + "default": "[Authelia] {title}" + }, + "startup_check_address": { + "oneOf": [ + { + "type": "string", + "pattern": "^[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$" + }, + { + "type": "string", + "pattern": "^[^\u003c]+ \u003c[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*\u003e$" + } + ], + "title": "Startup Check Address", + "description": "The address used for the recipient in the startup check" + }, + "disable_require_tls": { + "type": "boolean", + "title": "Disable Require TLS", + "description": "Disables the requirement to use TLS", + "default": false + }, + "disable_html_emails": { + "type": "boolean", + "title": "Disable HTML Emails", + "description": "Disables the mixed content type of emails and only sends the plaintext version", + "default": false + }, + "disable_starttls": { + "type": "boolean", + "title": "Disable StartTLS", + "description": "Disables the opportunistic StartTLS functionality which is useful for bad SMTP servers which advertise support for it but don't actually support it'", + "default": false + }, + "tls": { + "$ref": "#/$defs/TLS", + "title": "TLS", + "description": "The SMTP server TLS connection properties" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "NotifierSMTP represents the configuration of the SMTP server to send emails with." + }, + "PasswordDigest": { + "type": "string", + "pattern": "^\\$((argon2(id|i|d)\\$v=19\\$m=\\d+,t=\\d+,p=\\d+|scrypt\\$ln=\\d+,r=\\d+,p=\\d+)\\$[a-zA-Z0-9\\/+]+\\$[a-zA-Z0-9\\/+]+|pbkdf2(-sha(224|256|384|512))?\\$\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|bcrypt-sha256\\$v=2,t=2b,r=\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|2(a|b|y)?\\$\\d+\\$[a-zA-Z0-9.\\/]+|(5|6)\\$rounds=\\d+\\$[a-zA-Z0-9.\\/]+\\$[a-zA-Z0-9.\\/]+|plaintext\\$.+|base64\\$[a-zA-Z0-9.=\\/]+)$" + }, + "PasswordPolicy": { + "properties": { + "standard": { + "$ref": "#/$defs/PasswordPolicyStandard", + "title": "Standard", + "description": "The standard password policy engine" + }, + "zxcvbn": { + "$ref": "#/$defs/PasswordPolicyZXCVBN", + "title": "ZXCVBN", + "description": "The ZXCVBN password policy engine" + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicy represents the configuration related to password policy." + }, + "PasswordPolicyStandard": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the standard password policy engine", + "default": false + }, + "min_length": { + "type": "integer", + "title": "Minimum Length", + "description": "Minimum password length" + }, + "max_length": { + "type": "integer", + "title": "Maximum Length", + "description": "Maximum password length", + "default": 8 + }, + "require_uppercase": { + "type": "boolean", + "title": "Require Uppercase", + "description": "Require uppercase characters", + "default": false + }, + "require_lowercase": { + "type": "boolean", + "title": "Require Lowercase", + "description": "Require lowercase characters", + "default": false + }, + "require_number": { + "type": "boolean", + "title": "Require Number", + "description": "Require numeric characters", + "default": false + }, + "require_special": { + "type": "boolean", + "title": "Require Special", + "description": "Require symbolic characters", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicyStandard represents the configuration related to standard parameters of password policy." + }, + "PasswordPolicyZXCVBN": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the ZXCVBN password policy engine", + "default": false + }, + "min_score": { + "type": "integer", + "title": "Minimum Score", + "description": "The minimum ZXCVBN score allowed", + "default": 3 + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicyZXCVBN represents the configuration related to ZXCVBN parameters of password policy." + }, + "PrivacyPolicy": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the Privacy Policy functionality", + "default": false + }, + "require_user_acceptance": { + "type": "boolean", + "title": "Require User Acceptance", + "description": "Enables the requirement for users to accept the policy", + "default": false + }, + "policy_url": { + "type": "string", + "format": "uri", + "title": "Policy URL", + "description": "The URL of the privacy policy" + } + }, + "additionalProperties": false, + "type": "object", + "description": "PrivacyPolicy is the privacy policy configuration." + }, + "Regulation": { + "properties": { + "max_retries": { + "type": "integer", + "title": "Maximum Retries", + "description": "The maximum number of failed attempts permitted before banning a user", + "default": 3 + }, + "find_time": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Find Time", + "description": "The amount of time to consider when determining the number of failed attempts" + }, + "ban_time": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Ban Time", + "description": "The amount of time to ban the user for when it's determined the maximum retries has been exceeded'" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Regulation represents the configuration related to regulation." + }, + "Server": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address to listen on" + }, + "asset_path": { + "type": "string", + "title": "Asset Path", + "description": "The directory where the server asset overrides reside" + }, + "disable_healthcheck": { + "type": "boolean", + "title": "Disable Healthcheck", + "description": "Disables the healthcheck functionality", + "default": false + }, + "tls": { + "$ref": "#/$defs/ServerTLS", + "title": "TLS", + "description": "The server TLS configuration" + }, + "headers": { + "$ref": "#/$defs/ServerHeaders", + "title": "Headers", + "description": "The server headers configuration" + }, + "endpoints": { + "$ref": "#/$defs/ServerEndpoints", + "title": "Endpoints", + "description": "The server endpoints configuration" + }, + "buffers": { + "$ref": "#/$defs/ServerBuffers", + "title": "Buffers", + "description": "The server buffers configuration" + }, + "timeouts": { + "$ref": "#/$defs/ServerTimeouts", + "title": "Timeouts", + "description": "The server timeouts configuration" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "path": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Server represents the configuration of the http server." + }, + "ServerBuffers": { + "properties": { + "read": { + "type": "integer", + "title": "Read", + "description": "The read buffer size", + "default": 4096 + }, + "write": { + "type": "integer", + "title": "Write", + "description": "The write buffer size", + "default": 4096 + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerBuffers represents server buffer configurations." + }, + "ServerEndpoints": { + "properties": { + "enable_pprof": { + "type": "boolean", + "title": "Enable PProf", + "description": "Enables the developer specific pprof endpoints which should not be used in production and only used for debugging purposes", + "default": false + }, + "enable_expvars": { + "type": "boolean", + "title": "Enable ExpVars", + "description": "Enables the developer specific ExpVars endpoints which should not be used in production and only used for debugging purposes", + "default": false + }, + "authz": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/ServerEndpointsAuthz" + } + }, + "type": "object", + "title": "Authz", + "description": "Configures the Authorization endpoints" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpoints is the endpoints configuration for the HTTP server." + }, + "ServerEndpointsAuthz": { + "properties": { + "implementation": { + "type": "string", + "enum": [ + "ForwardAuth", + "AuthRequest", + "ExtAuthz", + "Legacy" + ], + "title": "Implementation", + "description": "The specific Authorization implementation to use for this endpoint" + }, + "authn_strategies": { + "items": { + "$ref": "#/$defs/ServerEndpointsAuthzAuthnStrategy" + }, + "type": "array", + "title": "Authn Strategies", + "description": "The specific Authorization strategies to use for this endpoint" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpointsAuthz is the Authz endpoints configuration for the HTTP server." + }, + "ServerEndpointsAuthzAuthnStrategy": { + "properties": { + "name": { + "type": "string", + "enum": [ + "HeaderAuthorization", + "HeaderProxyAuthorization", + "HeaderAuthRequestProxyAuthorization", + "HeaderLegacy", + "CookieSession" + ], + "title": "Name", + "description": "The name of the Authorization strategy to use" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpointsAuthzAuthnStrategy is the Authz endpoints configuration for the HTTP server." + }, + "ServerHeaders": { + "properties": { + "csp_template": { + "type": "string", + "title": "CSP Template", + "description": "The Content Security Policy template", + "default": "default-src 'self'; frame-src 'none'; object-src 'none'; style-src 'self' 'nonce-%s'; frame-ancestors 'none'; base-uri 'self'" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerHeaders represents the customization of the http server headers." + }, + "ServerTLS": { + "properties": { + "certificate": { + "type": "string", + "title": "Certificate", + "description": "Path to the Certificate" + }, + "key": { + "type": "string", + "title": "Key", + "description": "Path to the Private Key" + }, + "client_certificates": { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true, + "title": "Client Certificates", + "description": "Path to the Client Certificates to trust for mTLS" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerTLS represents the configuration of the http servers TLS options." + }, + "ServerTimeouts": { + "properties": { + "read": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Read", + "description": "The read timeout" + }, + "write": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Write", + "description": "The write timeout" + }, + "idle": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Idle", + "description": "The idle timeout" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerTimeouts represents server timeout configurations." + }, + "Session": { + "properties": { + "name": { + "type": "string", + "default": "authelia_session" + }, + "same_site": { + "type": "string", + "enum": [ + "lax", + "strict", + "none" + ], + "default": "lax" + }, + "expiration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "inactivity": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "remember_me": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "DisableRememberMe": { + "type": "boolean" + }, + "secret": { + "type": "string", + "title": "Secret", + "description": "Secret used to encrypt the session data" + }, + "cookies": { + "items": { + "$ref": "#/$defs/SessionCookie" + }, + "type": "array", + "title": "Cookies", + "description": "List of cookie domain configurations" + }, + "redis": { + "$ref": "#/$defs/SessionRedis", + "title": "Redis", + "description": "Redis Session Provider configuration" + }, + "domain": { + "type": "string", + "description": "Deprecated: Use the cookies options instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Session represents the configuration related to user sessions." + }, + "SessionCookie": { + "properties": { + "name": { + "type": "string", + "default": "authelia_session" + }, + "same_site": { + "type": "string", + "enum": [ + "lax", + "strict", + "none" + ], + "default": "lax" + }, + "expiration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "inactivity": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "remember_me": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "DisableRememberMe": { + "type": "boolean" + }, + "domain": { + "type": "string", + "format": "hostname", + "title": "Domain", + "description": "The domain for this session cookie" + }, + "authelia_url": { + "type": "string", + "format": "uri", + "title": "Authelia URL", + "description": "The Root Authelia URL to redirect users to for this session cookie" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionCookie represents the configuration for a cookie domain." + }, + "SessionRedis": { + "properties": { + "host": { + "type": "string", + "title": "Host", + "description": "The redis server host" + }, + "port": { + "type": "integer", + "title": "Host", + "description": "The redis server port", + "default": 6379 + }, + "username": { + "type": "string", + "title": "Username", + "description": "The redis username" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The redis password" + }, + "database_index": { + "type": "integer", + "title": "Database Index", + "description": "The redis database index", + "default": 0 + }, + "maximum_active_connections": { + "type": "integer", + "title": "Maximum Active Connections", + "description": "The maximum connections that can be made to redis at one time", + "default": 8 + }, + "minimum_idle_connections": { + "type": "integer", + "title": "Minimum Idle Connections", + "description": "The minimum idle connections that should be open to redis" + }, + "tls": { + "$ref": "#/$defs/TLS" + }, + "high_availability": { + "$ref": "#/$defs/SessionRedisHighAvailability" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedis represents the configuration related to redis session store." + }, + "SessionRedisHighAvailability": { + "properties": { + "sentinel_name": { + "type": "string", + "title": "Sentinel Name", + "description": "The name of the sentinel instance" + }, + "sentinel_username": { + "type": "string", + "title": "Sentinel Username", + "description": "The username for the sentinel instance" + }, + "sentinel_password": { + "type": "string", + "title": "Sentinel Username", + "description": "The username for the sentinel instance" + }, + "route_by_latency": { + "type": "boolean", + "title": "Route by Latency", + "description": "Uses the Route by Latency mode", + "default": false + }, + "route_randomly": { + "type": "boolean", + "title": "Route Randomly", + "description": "Uses the Route Randomly mode", + "default": false + }, + "nodes": { + "items": { + "$ref": "#/$defs/SessionRedisHighAvailabilityNode" + }, + "type": "array", + "title": "Nodes", + "description": "The pre-populated list of nodes for the sentinel instance" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedisHighAvailability holds configuration variables for Redis Cluster/Sentinel." + }, + "SessionRedisHighAvailabilityNode": { + "properties": { + "host": { + "type": "string", + "title": "Host", + "description": "The redis sentinel node host" + }, + "port": { + "type": "integer", + "title": "Port", + "description": "The redis sentinel node port", + "default": 26379 + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedisHighAvailabilityNode Represents a Node." + }, + "Storage": { + "properties": { + "local": { + "$ref": "#/$defs/StorageLocal", + "title": "Local", + "description": "The Local SQLite3 Storage configuration settings" + }, + "mysql": { + "$ref": "#/$defs/StorageMySQL", + "title": "MySQL", + "description": "The MySQL/MariaDB Storage configuration settings" + }, + "postgres": { + "$ref": "#/$defs/StoragePostgreSQL", + "title": "PostgreSQL", + "description": "The PostgreSQL Storage configuration settings" + }, + "encryption_key": { + "type": "string", + "title": "Encryption Key", + "description": "The Storage Encryption Key used to secure security sensitive values in the storage engine" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Storage represents the configuration of the storage backend." + }, + "StorageLocal": { + "properties": { + "path": { + "type": "string", + "title": "Path", + "description": "The Path for the SQLite3 database file" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StorageLocal represents the configuration when using local storage." + }, + "StorageMySQL": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address of the database" + }, + "database": { + "type": "string", + "title": "Database", + "description": "The database name to use upon a successful connection" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username to use to authenticate" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password to use to authenticate" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The timeout for the database connection" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "tls": { + "$ref": "#/$defs/TLS" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StorageMySQL represents the configuration of a MySQL database." + }, + "StoragePostgreSQL": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address of the database" + }, + "database": { + "type": "string", + "title": "Database", + "description": "The database name to use upon a successful connection" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username to use to authenticate" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password to use to authenticate" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The timeout for the database connection" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "schema": { + "type": "string", + "default": "public" + }, + "tls": { + "$ref": "#/$defs/TLS" + }, + "ssl": { + "$ref": "#/$defs/StoragePostgreSQLSSL", + "description": "Deprecated: Use the TLS configuration instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "StoragePostgreSQL represents the configuration of a PostgreSQL database." + }, + "StoragePostgreSQLSSL": { + "properties": { + "mode": { + "type": "string", + "deprecated": true + }, + "root_certificate": { + "type": "string", + "deprecated": true + }, + "certificate": { + "type": "string", + "deprecated": true + }, + "key": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StoragePostgreSQLSSL represents the SSL configuration of a PostgreSQL database." + }, + "TLS": { + "properties": { + "minimum_version": { + "$ref": "#/$defs/TLSVersion", + "title": "Minimum Version", + "description": "The minimum TLS version accepted" + }, + "maximum_version": { + "$ref": "#/$defs/TLSVersion", + "title": "Maximum Version", + "description": "The maximum TLS version accepted" + }, + "skip_verify": { + "type": "boolean", + "title": "Skip Verify", + "description": "Disable all verification of the TLS properties", + "default": false + }, + "server_name": { + "type": "string", + "format": "hostname", + "title": "Server Name", + "description": "The expected server name to match the certificate against" + }, + "private_key": { + "type": "string", + "pattern": "^-{5}(BEGIN ((RSA|EC) )?PRIVATE KEY-{5}\\n([a-zA-Z0-9/+]{1,64}\\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\\n-{5}END ((RSA|EC) )?PRIVATE KEY-{5}\\n?)+$", + "title": "Private Key", + "description": "The private key" + }, + "certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Certificate Chain", + "description": "The certificate chain" + } + }, + "additionalProperties": false, + "type": "object", + "description": "TLS is a representation of the TLS configuration." + }, + "TLSVersion": { + "type": "string", + "enum": [ + "TLS1.0", + "TLS1.1", + "TLS1.2", + "TLS1.3" + ] + }, + "TOTP": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the TOTP 2FA functionality", + "default": false + }, + "issuer": { + "type": "string", + "title": "Issuer", + "description": "The issuer value for generated TOTP keys", + "default": "Authelia" + }, + "algorithm": { + "type": "string", + "enum": [ + "SHA1", + "SHA256", + "SHA512" + ], + "title": "Algorithm", + "description": "The algorithm value for generated TOTP keys", + "default": "SHA1" + }, + "digits": { + "type": "integer", + "enum": [ + 6, + 8 + ], + "title": "Digits", + "description": "The digits value for generated TOTP keys", + "default": 6 + }, + "period": { + "type": "integer", + "title": "Period", + "description": "The period value for generated TOTP keys", + "default": 30 + }, + "skew": { + "type": "integer", + "title": "Skew", + "description": "The permitted skew for generated TOTP keys", + "default": 1 + }, + "secret_size": { + "type": "integer", + "minimum": 20, + "title": "Secret Size", + "description": "The secret size for generated TOTP keys", + "default": 32 + } + }, + "additionalProperties": false, + "type": "object", + "description": "TOTP represents the configuration related to TOTP options." + }, + "Telemetry": { + "properties": { + "metrics": { + "$ref": "#/$defs/TelemetryMetrics", + "title": "Metrics", + "description": "The telemetry metrics server configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Telemetry represents the telemetry config." + }, + "TelemetryMetrics": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the metrics server", + "default": false + }, + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address for the metrics server to listen on" + }, + "buffers": { + "$ref": "#/$defs/ServerBuffers", + "title": "Buffers", + "description": "The server buffers configuration for the metrics server" + }, + "timeouts": { + "$ref": "#/$defs/ServerTimeouts", + "title": "Timeouts", + "description": "The server timeouts configuration for the metrics server" + } + }, + "additionalProperties": false, + "type": "object", + "description": "TelemetryMetrics represents the telemetry metrics config." + }, + "WebAuthn": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the WebAuthn 2FA functionality", + "default": false + }, + "display_name": { + "type": "string", + "title": "Display Name", + "description": "The display name attribute for the WebAuthn relying party", + "default": "Authelia" + }, + "attestation_conveyance_preference": { + "type": "string", + "enum": [ + "none", + "indirect", + "direct" + ], + "title": "Conveyance Preference", + "description": "The default conveyance preference for all WebAuthn credentials", + "default": "indirect" + }, + "user_verification": { + "type": "string", + "enum": [ + "discouraged", + "preferred", + "required" + ], + "title": "User Verification", + "description": "The default user verification preference for all WebAuthn credentials", + "default": "preferred" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The default timeout for all WebAuthn ceremonies" + } + }, + "additionalProperties": false, + "type": "object", + "description": "WebAuthn represents the webauthn config." + }, + "X509CertificateChain": { + "type": "string", + "pattern": "^(-{5}BEGIN CERTIFICATE-{5}\\n([a-zA-Z0-9/+]{1,64}\\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\\n-{5}END CERTIFICATE-{5}\\n?)+$" + } + } +} \ No newline at end of file diff --git a/docs/static/schemas/latest/user-database.json b/docs/static/schemas/latest/user-database.json new file mode 100644 index 000000000..51853c6ae --- /dev/null +++ b/docs/static/schemas/latest/user-database.json @@ -0,0 +1,71 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.authelia.com/v4.38/json-schema/user-database.json", + "$ref": "#/$defs/FileUserDatabase", + "$defs": { + "FileUserDatabase": { + "properties": { + "users": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/FileUserDatabaseUserDetails" + } + }, + "type": "object", + "title": "Users", + "description": "The dictionary of users" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "users" + ], + "description": "FileUserDatabase is a user details database that is concurrency safe database and can be reloaded." + }, + "FileUserDatabaseUserDetails": { + "properties": { + "password": { + "$ref": "#/$defs/PasswordDigest", + "title": "Password", + "description": "The hashed password for the user" + }, + "displayname": { + "type": "string", + "title": "Display Name", + "description": "The display name for the user" + }, + "email": { + "type": "string", + "title": "Email", + "description": "The email for the user" + }, + "groups": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Groups", + "description": "The groups list for the user" + }, + "disabled": { + "type": "boolean", + "title": "Disabled", + "description": "The disabled status for the user", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "password", + "displayname" + ], + "description": "FileUserDatabaseUserDetails is the model of user details in the file database." + }, + "PasswordDigest": { + "type": "string", + "pattern": "^\\$((argon2(id|i|d)\\$v=19\\$m=\\d+,t=\\d+,p=\\d+|scrypt\\$ln=\\d+,r=\\d+,p=\\d+)\\$[a-zA-Z0-9\\/+]+\\$[a-zA-Z0-9\\/+]+|pbkdf2(-sha(224|256|384|512))?\\$\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|bcrypt-sha256\\$v=2,t=2b,r=\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|2(a|b|y)?\\$\\d+\\$[a-zA-Z0-9.\\/]+|(5|6)\\$rounds=\\d+\\$[a-zA-Z0-9.\\/]+\\$[a-zA-Z0-9.\\/]+|plaintext\\$.+|base64\\$[a-zA-Z0-9.=\\/]+)$" + } + } +} \ No newline at end of file diff --git a/docs/static/schemas/v4.38/configuration.json b/docs/static/schemas/v4.38/configuration.json new file mode 100644 index 000000000..e74be8b58 --- /dev/null +++ b/docs/static/schemas/v4.38/configuration.json @@ -0,0 +1,2866 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.authelia.com/v4.38/json-schema/configuration.json", + "$ref": "#/$defs/Configuration", + "$defs": { + "AccessControl": { + "properties": { + "default_policy": { + "type": "string", + "enum": [ + "deny", + "one_factor", + "two_factor" + ], + "title": "Default Authorization Policy", + "description": "The default policy applied to all authorization requests. Not relevant to OpenID Connect.", + "default": "deny" + }, + "networks": { + "items": { + "$ref": "#/$defs/AccessControlNetwork" + }, + "type": "array", + "title": "Named Networks", + "description": "The list of named networks which can be reused in any ACL rule" + }, + "rules": { + "items": { + "$ref": "#/$defs/AccessControlRule" + }, + "type": "array", + "title": "Rules List", + "description": "The list of ACL rules to enumerate for requests" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AccessControl represents the configuration related to ACLs." + }, + "AccessControlNetwork": { + "properties": { + "name": { + "type": "string", + "title": "Network Name", + "description": "The name of this network to be used in the networks section of the rules section" + }, + "networks": { + "$ref": "#/$defs/AccessControlNetworkNetworks", + "title": "Networks", + "description": "The remote IP's or network ranges in CIDR notation that this rule applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "networks" + ], + "description": "AccessControlNetwork represents one ACL network group entry." + }, + "AccessControlNetworkNetworks": { + "oneOf": [ + { + "type": "string", + "pattern": "((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\\/([0-2]?[0-9]|3[0-2]))?$)|(^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))?(\\/(12[0-8]|1[0-1][0-9]|[0-9]{1,2}))?$))" + }, + { + "items": { + "type": "string", + "pattern": "((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\\/([0-2]?[0-9]|3[0-2]))?$)|(^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))?(\\/(12[0-8]|1[0-1][0-9]|[0-9]{1,2}))?$))" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRule": { + "oneOf": [ + { + "required": [ + "domain" + ], + "title": "Domain" + }, + { + "required": [ + "domain_regex" + ], + "title": "Domain Regex" + } + ], + "properties": { + "domain": { + "$ref": "#/$defs/AccessControlRuleDomains", + "title": "Domain Literals", + "description": "The literal domains to match the domain against that this rule applies to" + }, + "domain_regex": { + "$ref": "#/$defs/AccessControlRuleRegex", + "title": "Domain Regex Patterns", + "description": "The regex patterns to match the domain against that this rule applies to" + }, + "policy": { + "type": "string", + "enum": [ + "bypass", + "deny", + "one_factor", + "two_factor" + ], + "title": "Rule Policy", + "description": "The policy this rule applies when all criteria match" + }, + "subject": { + "$ref": "#/$defs/AccessControlRuleSubjects", + "title": "AccessControlRuleSubjects", + "description": "The users or groups that this rule applies to" + }, + "networks": { + "$ref": "#/$defs/AccessControlRuleNetworks", + "title": "Networks", + "description": "The remote IP's, network ranges in CIDR notation, or network names that this rule applies to" + }, + "resources": { + "$ref": "#/$defs/AccessControlRuleRegex", + "title": "Resources or Paths", + "description": "The regex patterns to match the resource paths that this rule applies to" + }, + "methods": { + "$ref": "#/$defs/AccessControlRuleMethods", + "description": "The list of request methods this rule applies to" + }, + "query": { + "items": { + "items": { + "$ref": "#/$defs/AccessControlRuleQuery" + }, + "type": "array" + }, + "type": "array", + "title": "Query Rules", + "description": "The list of query parameter rules this rule applies to" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "policy" + ], + "description": "AccessControlRule represents one ACL rule entry." + }, + "AccessControlRuleDomains": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleMethods": { + "oneOf": [ + { + "type": "string", + "enum": [ + "GET", + "HEAD", + "POST", + "PUT", + "PATCH", + "DELETE", + "TRACE", + "CONNECT", + "OPTIONS", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK" + ] + }, + { + "items": { + "type": "string", + "enum": [ + "GET", + "HEAD", + "POST", + "PUT", + "PATCH", + "DELETE", + "TRACE", + "CONNECT", + "OPTIONS", + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK" + ] + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleNetworks": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleQuery": { + "properties": { + "operator": { + "type": "string", + "enum": [ + "equal", + "not equal", + "present", + "absent", + "pattern", + "not pattern" + ], + "title": "Operator", + "description": "The list of query parameter rules this rule applies to" + }, + "key": { + "type": "string", + "title": "Key", + "description": "The Query Parameter key this rule applies to" + }, + "value": { + "title": "Value", + "description": "The Query Parameter value for this rule" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "key" + ], + "description": "AccessControlRuleQuery represents the ACL query criteria." + }, + "AccessControlRuleRegex": { + "oneOf": [ + { + "type": "string", + "format": "regex" + }, + { + "items": { + "type": "string", + "format": "regex" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AccessControlRuleSubjects": { + "oneOf": [ + { + "type": "string", + "pattern": "^(user|group):.+$" + }, + { + "items": { + "type": "string", + "pattern": "^(user|group):.+$" + }, + "type": "array" + }, + { + "items": { + "items": { + "type": "string", + "pattern": "^(user|group):.+$" + }, + "type": "array" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "AddressLDAP": { + "type": "string", + "pattern": "^((ldaps?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)?|ldapi:\\/\\/(\\/[^?\\n]+)?)$", + "format": "uri" + }, + "AddressSMTP": { + "type": "string", + "pattern": "^((smtp|submissions?):\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)?$", + "format": "uri" + }, + "AddressTCP": { + "type": "string", + "pattern": "^((tcp(4|6)?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)(\\/.*)?|unix:\\/\\/\\/[^?\\n]+(\\?umask=[0-7]{3,4})?)$", + "format": "uri" + }, + "AddressUDP": { + "type": "string", + "pattern": "^(udp(4|6)?:\\/\\/)?([^:\\/]*(:\\d+)|[^:\\/]+(:\\d+)?)(\\/.*)?$", + "format": "uri" + }, + "AuthenticationBackend": { + "properties": { + "password_reset": { + "$ref": "#/$defs/AuthenticationBackendPasswordReset", + "title": "Password Reset", + "description": "Allows configuration of the password reset behaviour" + }, + "refresh_interval": { + "type": "string", + "title": "Refresh Interval", + "description": "How frequently the user details are refreshed from the backend" + }, + "file": { + "$ref": "#/$defs/AuthenticationBackendFile", + "title": "File Backend", + "description": "The file authentication backend configuration" + }, + "ldap": { + "$ref": "#/$defs/AuthenticationBackendLDAP", + "title": "LDAP Backend", + "description": "The LDAP authentication backend configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackend represents the configuration related to the authentication backend." + }, + "AuthenticationBackendFile": { + "properties": { + "path": { + "type": "string", + "title": "Path", + "description": "The file path to the user database" + }, + "watch": { + "type": "boolean", + "title": "Watch", + "description": "Enables watching the file for external changes and dynamically reloading the database", + "default": false + }, + "password": { + "$ref": "#/$defs/AuthenticationBackendFilePassword", + "title": "Password Options", + "description": "Allows configuration of the password hashing options when the user passwords are changed directly by Authelia" + }, + "search": { + "$ref": "#/$defs/AuthenticationBackendFileSearch", + "title": "Search", + "description": "Configures the user searching behaviour" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFile represents the configuration related to file-based backend." + }, + "AuthenticationBackendFilePassword": { + "properties": { + "algorithm": { + "type": "string", + "enum": [ + "argon2", + "sha2crypt", + "pbkdf2", + "bcrypt", + "scrypt" + ], + "title": "Algorithm", + "description": "The password hashing algorithm to use", + "default": "argon2" + }, + "argon2": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordArgon2", + "title": "Argon2", + "description": "Configure the Argon2 password hashing parameters" + }, + "sha2crypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordSHA2Crypt", + "title": "SHA2Crypt", + "description": "Configure the SHA2Crypt password hashing parameters" + }, + "pbkdf2": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordPBKDF2", + "title": "PBKDF2", + "description": "Configure the PBKDF2 password hashing parameters" + }, + "bcrypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordBCrypt", + "title": "BCrypt", + "description": "Configure the BCrypt password hashing parameters" + }, + "scrypt": { + "$ref": "#/$defs/AuthenticationBackendFilePasswordSCrypt", + "title": "SCrypt", + "description": "Configure the SCrypt password hashing parameters" + }, + "iterations": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "memory": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "parallelism": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "key_length": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + }, + "salt_length": { + "type": "integer", + "description": "Deprecated: Use individual password options instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePassword represents the configuration related to password hashing." + }, + "AuthenticationBackendFilePasswordArgon2": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "argon2id", + "argon2i", + "argon2d" + ], + "title": "Variant", + "description": "The Argon2 variant to be used", + "default": "argon2id" + }, + "iterations": { + "type": "integer", + "title": "Iterations", + "description": "The number of Argon2 iterations (parameter t) to be used", + "default": 3 + }, + "memory": { + "type": "integer", + "maximum": 4294967295, + "minimum": 8, + "title": "Memory", + "description": "The Argon2 amount of memory in kibibytes (parameter m) to be used", + "default": 65536 + }, + "parallelism": { + "type": "integer", + "maximum": 16777215, + "minimum": 1, + "title": "Parallelism", + "description": "The Argon2 degree of parallelism (parameter p) to be used", + "default": 4 + }, + "key_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 4, + "title": "Key Length", + "description": "The Argon2 key output length", + "default": 32 + }, + "salt_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 1, + "title": "Salt Length", + "description": "The Argon2 salt length", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordArgon2 represents the argon2 hashing settings." + }, + "AuthenticationBackendFilePasswordBCrypt": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "standard", + "sha256" + ], + "title": "Variant", + "description": "The BCrypt variant to be used", + "default": "standard" + }, + "cost": { + "type": "integer", + "maximum": 31, + "minimum": 10, + "title": "Cost", + "description": "The BCrypt cost to be used", + "default": 12 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordBCrypt represents the bcrypt hashing settings." + }, + "AuthenticationBackendFilePasswordPBKDF2": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ], + "title": "Variant", + "description": "The PBKDF2 variant to be used", + "default": "sha512" + }, + "iterations": { + "type": "integer", + "maximum": 2147483647, + "minimum": 100000, + "title": "Iterations", + "description": "The PBKDF2 iterations to be used", + "default": 310000 + }, + "salt_length": { + "type": "integer", + "maximum": 2147483647, + "minimum": 8, + "title": "Salt Length", + "description": "The PBKDF2 salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordPBKDF2 represents the PBKDF2 hashing settings." + }, + "AuthenticationBackendFilePasswordSCrypt": { + "properties": { + "iterations": { + "type": "integer", + "maximum": 58, + "minimum": 1, + "title": "Iterations", + "description": "The SCrypt iterations to be used", + "default": 16 + }, + "block_size": { + "type": "integer", + "maximum": 36028797018963967, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt block size to be used", + "default": 8 + }, + "parallelism": { + "type": "integer", + "maximum": 1073741823, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt parallelism factor to be used", + "default": 1 + }, + "key_length": { + "type": "integer", + "maximum": 137438953440, + "minimum": 1, + "title": "Key Length", + "description": "The SCrypt key length to be used", + "default": 32 + }, + "salt_length": { + "type": "integer", + "maximum": 1024, + "minimum": 8, + "title": "Salt Length", + "description": "The SCrypt salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordSCrypt represents the scrypt hashing settings." + }, + "AuthenticationBackendFilePasswordSHA2Crypt": { + "properties": { + "variant": { + "type": "string", + "enum": [ + "sha256", + "sha512" + ], + "title": "Variant", + "description": "The SHA2Crypt variant to be used", + "default": "sha512" + }, + "iterations": { + "type": "integer", + "maximum": 999999999, + "minimum": 1000, + "title": "Iterations", + "description": "The SHA2Crypt iterations (parameter rounds) to be used", + "default": 50000 + }, + "salt_length": { + "type": "integer", + "maximum": 16, + "minimum": 1, + "title": "Salt Length", + "description": "The SHA2Crypt salt length to be used", + "default": 16 + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFilePasswordSHA2Crypt represents the sha2crypt hashing settings." + }, + "AuthenticationBackendFileSearch": { + "properties": { + "email": { + "type": "boolean", + "title": "Email Searching", + "description": "Allows users to either use their username or their configured email as a username", + "default": false + }, + "case_insensitive": { + "type": "boolean", + "title": "Case Insensitive Searching", + "description": "Allows usernames to be any case during the search", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendFileSearch represents the configuration related to file-based backend searching." + }, + "AuthenticationBackendLDAP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressLDAP", + "title": "Address", + "description": "The address of the LDAP directory server" + }, + "implementation": { + "type": "string", + "enum": [ + "custom", + "activedirectory", + "rfc2307bis", + "freeipa", + "lldap", + "glauth" + ], + "title": "Implementation", + "description": "The implementation which mostly decides the default values", + "default": "custom" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The LDAP directory server connection timeout" + }, + "start_tls": { + "type": "boolean", + "title": "StartTLS", + "description": "Enables the use of StartTLS", + "default": false + }, + "tls": { + "$ref": "#/$defs/TLS", + "title": "TLS", + "description": "The LDAP directory server TLS connection properties" + }, + "base_dn": { + "type": "string", + "title": "Base DN", + "description": "The base for all directory server operations" + }, + "additional_users_dn": { + "type": "string", + "title": "Additional User Base", + "description": "The base in addition to the Base DN for all directory server operations for users" + }, + "users_filter": { + "type": "string", + "title": "Users Filter", + "description": "The LDAP filter used to search for user objects" + }, + "additional_groups_dn": { + "type": "string", + "title": "Additional Group Base", + "description": "The base in addition to the Base DN for all directory server operations for groups" + }, + "groups_filter": { + "type": "string", + "title": "Groups Filter", + "description": "The LDAP filter used to search for group objects" + }, + "GroupSearchMode": { + "type": "string" + }, + "attributes": { + "$ref": "#/$defs/AuthenticationBackendLDAPAttributes" + }, + "permit_referrals": { + "type": "boolean", + "title": "Permit Referrals", + "description": "Enables chasing LDAP referrals", + "default": false + }, + "permit_unauthenticated_bind": { + "type": "boolean", + "title": "Permit Unauthenticated Bind", + "description": "Enables omission of the password to perform an unauthenticated bind", + "default": false + }, + "permit_feature_detection_failure": { + "type": "boolean", + "title": "Permit Feature Detection Failure", + "description": "Enables failures when detecting directory server features using the Root DSE lookup", + "default": false + }, + "user": { + "type": "string", + "title": "User", + "description": "The user distinguished name for LDAP binding" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password for LDAP authenticated binding" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendLDAP represents the configuration related to LDAP server." + }, + "AuthenticationBackendLDAPAttributes": { + "properties": { + "distinguished_name": { + "type": "string", + "title": "Attribute: Distinguished Name", + "description": "The directory server attribute which contains the distinguished name for all objects" + }, + "username": { + "type": "string", + "title": "Attribute: User Username", + "description": "The directory server attribute which contains the username for all users" + }, + "display_name": { + "type": "string", + "title": "Attribute: User Display Name", + "description": "The directory server attribute which contains the display name for all users" + }, + "mail": { + "type": "string", + "title": "Attribute: User Mail", + "description": "The directory server attribute which contains the mail address for all users and groups" + }, + "MemberOf": { + "type": "string", + "title": "Attribute: Member Of", + "description": "The directory server attribute which contains the objects that an object is a member of" + }, + "group_name": { + "type": "string", + "title": "Attribute: Group Name", + "description": "The directory server attribute which contains the group name for all groups" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendLDAPAttributes represents the configuration related to LDAP server attributes." + }, + "AuthenticationBackendPasswordReset": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the Password Reset option", + "default": false + }, + "custom_url": { + "type": "string", + "format": "uri", + "description": "Disables the internal Password Reset option and instead redirects users to this specified URL" + } + }, + "additionalProperties": false, + "type": "object", + "description": "AuthenticationBackendPasswordReset represents the configuration related to password reset functionality." + }, + "Configuration": { + "properties": { + "theme": { + "type": "string", + "enum": [ + "auto", + "light", + "dark", + "grey" + ], + "title": "Theme Name", + "description": "The name of the theme to apply to the web UI", + "default": "light" + }, + "certificates_directory": { + "type": "string", + "title": "Certificates Directory Path", + "description": "The path to a directory which is used to determine the certificates that are trusted" + }, + "jwt_secret": { + "type": "string", + "title": "Secret Key for JWT's", + "description": "Used for signing HS256 JWT's for identity verification" + }, + "default_redirection_url": { + "type": "string", + "title": "The default redirection URL", + "description": "Used to redirect users when they visit the portal directly" + }, + "default_2fa_method": { + "type": "string", + "enum": [ + "totp", + "webauthn", + "mobile_push" + ], + "title": "Default 2FA method", + "description": "When a user logs in for the first time this is the 2FA method configured for them" + }, + "log": { + "$ref": "#/$defs/Log", + "title": "Log", + "description": "Logging Configuration" + }, + "identity_providers": { + "$ref": "#/$defs/IdentityProviders", + "title": "Identity Providers", + "description": "Identity Providers Configuration" + }, + "authentication_backend": { + "$ref": "#/$defs/AuthenticationBackend", + "title": "Authentication Backend", + "description": "Authentication Backend Configuration" + }, + "session": { + "$ref": "#/$defs/Session", + "title": "Session", + "description": "Session Configuration" + }, + "totp": { + "$ref": "#/$defs/TOTP", + "title": "TOTP", + "description": "Time-based One Time Password Configuration" + }, + "duo_api": { + "$ref": "#/$defs/DuoAPI", + "title": "Duo API", + "description": "Duo API Configuration" + }, + "access_control": { + "$ref": "#/$defs/AccessControl", + "title": "Access Control", + "description": "Access Control Configuration" + }, + "ntp": { + "$ref": "#/$defs/NTP", + "title": "NTP", + "description": "Network Time Protocol Configuration" + }, + "regulation": { + "$ref": "#/$defs/Regulation", + "title": "Regulation", + "description": "Regulation Configuration" + }, + "storage": { + "$ref": "#/$defs/Storage", + "title": "Storage", + "description": "Storage Configuration" + }, + "notifier": { + "$ref": "#/$defs/Notifier", + "title": "Notifier", + "description": "Notifier Configuration" + }, + "server": { + "$ref": "#/$defs/Server", + "title": "Server", + "description": "Server Configuration" + }, + "telemetry": { + "$ref": "#/$defs/Telemetry", + "title": "Telemetry", + "description": "Telemetry Configuration" + }, + "webauthn": { + "$ref": "#/$defs/WebAuthn", + "title": "WebAuthn", + "description": "WebAuthn Configuration" + }, + "password_policy": { + "$ref": "#/$defs/PasswordPolicy", + "title": "Password Policy", + "description": "Password Policy Configuration" + }, + "privacy_policy": { + "$ref": "#/$defs/PrivacyPolicy", + "title": "Privacy Policy", + "description": "Privacy Policy Configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Configuration object extracted from YAML configuration file." + }, + "DuoAPI": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disable the Duo API integration", + "default": false + }, + "hostname": { + "type": "string", + "format": "hostname", + "title": "Hostname", + "description": "The Hostname provided by your Duo API dashboard" + }, + "integration_key": { + "type": "string", + "title": "Integration Key", + "description": "The Integration Key provided by your Duo API dashboard" + }, + "secret_key": { + "type": "string", + "title": "Secret Key", + "description": "The Secret Key provided by your Duo API dashboard" + }, + "enable_self_enrollment": { + "type": "boolean", + "title": "Enable Self Enrollment", + "description": "Enable the Self Enrollment flow", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "DuoAPI represents the configuration related to Duo API." + }, + "IdentityProviders": { + "properties": { + "oidc": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnect" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProviders represents the Identity Providers configuration for Authelia." + }, + "IdentityProvidersOpenIDConnect": { + "properties": { + "hmac_secret": { + "type": "string", + "title": "HMAC Secret", + "description": "The HMAC Secret used to sign Access Tokens" + }, + "issuer_private_keys": { + "items": { + "$ref": "#/$defs/JWK" + }, + "type": "array", + "title": "Issuer Private Keys", + "description": "The Private Keys used to sign ID Tokens" + }, + "issuer_certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Issuer Certificate Chain", + "description": "The Issuer Certificate Chain with an RSA Public Key used to sign ID Tokens" + }, + "issuer_private_key": { + "type": "string", + "title": "Issuer Private Key", + "description": "The Issuer Private Key with an RSA Private Key used to sign ID Tokens" + }, + "access_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Access Token Lifespan", + "description": "The duration an Access Token is valid for" + }, + "authorize_code_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Authorize Code Lifespan", + "description": "The duration an Authorization Code is valid for" + }, + "id_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "ID Token Lifespan", + "description": "The duration an ID Token is valid for" + }, + "refresh_token_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Refresh Token Lifespan", + "description": "The duration a Refresh Token is valid for" + }, + "enable_client_debug_messages": { + "type": "boolean", + "title": "Enable Client Debug Messages", + "description": "Enables additional debug messages for clients", + "default": false + }, + "minimum_parameter_entropy": { + "type": "integer", + "minimum": -1, + "title": "Minimum Parameter Entropy", + "description": "The minimum entropy of the nonce parameter", + "default": 8 + }, + "enforce_pkce": { + "type": "string", + "enum": [ + "public_clients_only", + "never", + "always" + ], + "title": "Enforce PKCE", + "description": "Controls enforcement of the use of Proof Key for Code Exchange on all clients", + "default": "public_clients_only" + }, + "enable_pkce_plain_challenge": { + "type": "boolean", + "title": "Enable PKCE Plain Challenge", + "description": "Enables use of the discouraged plain Proof Key for Code Exchange challenges", + "default": false + }, + "pushed_authorizations": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectPAR", + "title": "Pushed Authorizations", + "description": "Configuration options for Pushed Authorization Requests" + }, + "cors": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectCORS", + "title": "CORS", + "description": "Configuration options for Cross-Origin Request Sharing" + }, + "clients": { + "items": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClient" + }, + "type": "array", + "title": "Clients", + "description": "OpenID Connect 1.0 clients registry" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnect represents the configuration for OpenID Connect 1.0." + }, + "IdentityProvidersOpenIDConnectCORS": { + "properties": { + "endpoints": { + "items": { + "type": "string", + "enum": [ + "authorization", + "pushed-authorization-request", + "token", + "introspection", + "revocation", + "userinfo" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Endpoints", + "description": "List of endpoints to enable CORS handling for" + }, + "allowed_origins": { + "items": { + "type": "string", + "format": "uri" + }, + "type": "array", + "title": "Allowed Origins", + "description": "List of arbitrary allowed origins for CORS requests" + }, + "allowed_origins_from_client_redirect_uris": { + "type": "boolean", + "title": "Allowed Origins From Client Redirect URIs", + "description": "Automatically include the redirect URIs from the registered clients", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectCORS represents an OpenID Connect 1.0 CORS config." + }, + "IdentityProvidersOpenIDConnectClient": { + "properties": { + "id": { + "type": "string", + "minLength": 1, + "title": "ID", + "description": "The Client ID" + }, + "description": { + "type": "string", + "title": "Description", + "description": "The Client Description for End-Users" + }, + "secret": { + "$ref": "#/$defs/PasswordDigest", + "title": "Secret", + "description": "The Client Secret for Client Authentication" + }, + "sector_identifier": { + "type": "string", + "format": "uri", + "title": "Sector Identifier", + "description": "The Client Sector Identifier for Privacy Isolation" + }, + "public": { + "type": "boolean", + "title": "Public", + "description": "Enables the Public Client Type", + "default": false + }, + "redirect_uris": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClientRedirectURIs", + "title": "Redirect URIs", + "description": "List of authorized redirect URIs" + }, + "audience": { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true, + "title": "Audience", + "description": "List of authorized audiences" + }, + "scopes": { + "items": { + "type": "string", + "enum": [ + "openid", + "offline_access", + "groups", + "email", + "profile" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Scopes", + "description": "The Scopes this client is allowed request and be granted" + }, + "grant_types": { + "items": { + "type": "string", + "enum": [ + "authorization_code", + "implicit", + "refresh_token" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Grant Types", + "description": "The Grant Types this client is allowed to use for the protected endpoints" + }, + "response_types": { + "items": { + "type": "string", + "enum": [ + "code", + "id_token token", + "id_token", + "token", + "code token", + "code id_token", + "code id_token token" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Response Types", + "description": "The Response Types the client is authorized to request" + }, + "response_modes": { + "items": { + "type": "string", + "enum": [ + "form_post", + "query", + "fragment" + ] + }, + "type": "array", + "uniqueItems": true, + "title": "Response Modes", + "description": "The Response Modes this client is authorized request" + }, + "authorization_policy": { + "type": "string", + "title": "Authorization Policy", + "description": "The Authorization Policy to apply to this client" + }, + "consent_mode": { + "type": "string", + "enum": [ + "auto", + "explicit", + "implicit", + "pre-configured" + ], + "title": "Consent Mode", + "description": "The Consent Mode used for this client" + }, + "pre_configured_consent_duration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Pre-Configured Consent Duration", + "description": "The Pre-Configured Consent Duration when using Consent Mode pre-configured for this client" + }, + "enforce_par": { + "type": "boolean", + "title": "Enforce PAR", + "description": "Enforces Pushed Authorization Requests for this client", + "default": false + }, + "enforce_pkce": { + "type": "boolean", + "title": "Enforce PKCE", + "description": "Enforces Proof Key for Code Exchange for this client", + "default": false + }, + "pkce_challenge_method": { + "type": "string", + "enum": [ + "plain", + "S256" + ], + "title": "PKCE Challenge Method", + "description": "The PKCE Challenge Method enforced on this client" + }, + "id_token_signing_alg": { + "type": "string", + "enum": [ + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "ID Token Signing Algorithm", + "description": "The algorithm (JWA) this client uses to sign ID Tokens" + }, + "id_token_signing_key_id": { + "type": "string", + "title": "ID Token Signing Key ID", + "description": "The Key ID this client uses to sign ID Tokens (overrides the 'id_token_signing_alg')" + }, + "userinfo_signing_alg": { + "type": "string", + "enum": [ + "none", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Userinfo Signing Algorithm", + "description": "The Userinfo Endpoint Signing Algorithm this client uses" + }, + "userinfo_signing_key_id": { + "type": "string", + "title": "Userinfo Signing Key ID", + "description": "The Key ID this client uses to sign the userinfo responses (overrides the 'userinfo_token_signing_alg')" + }, + "request_object_signing_alg": { + "type": "string", + "enum": [ + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Request Object Signing Algorithm", + "description": "The Request Object Signing Algorithm the provider accepts for this client" + }, + "token_endpoint_auth_signing_alg": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Token Endpoint Auth Signing Algorithm", + "description": "The Token Endpoint Auth Signing Algorithm the provider accepts for this client" + }, + "token_endpoint_auth_method": { + "type": "string", + "enum": [ + "none", + "client_secret_post", + "client_secret_basic", + "private_key_jwt", + "client_secret_jwt" + ], + "title": "Token Endpoint Auth Method", + "description": "The Token Endpoint Auth Method enforced by the provider for this client" + }, + "public_keys": { + "$ref": "#/$defs/IdentityProvidersOpenIDConnectClientPublicKeys", + "title": "Public Keys", + "description": "Public Key options used to validate request objects and the 'private_key_jwt' client authentication method for this client" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "redirect_uris", + "scopes" + ], + "description": "IdentityProvidersOpenIDConnectClient represents a configuration for an OpenID Connect 1.0 client." + }, + "IdentityProvidersOpenIDConnectClientPublicKeys": { + "oneOf": [ + { + "required": [ + "uri" + ], + "title": "URI" + }, + { + "required": [ + "values" + ], + "title": "Values" + } + ], + "properties": { + "uri": { + "type": "string", + "format": "uri", + "title": "URI", + "description": "URI of the JWKS endpoint which contains the Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client" + }, + "values": { + "items": { + "$ref": "#/$defs/JWK" + }, + "type": "array", + "title": "Values", + "description": "List of arbitrary Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectClientPublicKeys represents the Client Public Keys configuration for an OpenID Connect 1.0 client." + }, + "IdentityProvidersOpenIDConnectClientRedirectURIs": { + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "items": { + "type": "string", + "format": "uri" + }, + "type": "array", + "uniqueItems": true + } + ] + }, + "IdentityProvidersOpenIDConnectPAR": { + "properties": { + "enforce": { + "type": "boolean", + "title": "Enforce", + "description": "Enforce the use of PAR for all requests on all clients", + "default": false + }, + "context_lifespan": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Context Lifespan", + "description": "How long a PAR context is valid for" + } + }, + "additionalProperties": false, + "type": "object", + "description": "IdentityProvidersOpenIDConnectPAR represents an OpenID Connect 1.0 PAR config." + }, + "JWK": { + "properties": { + "key_id": { + "type": "string", + "maxLength": 100, + "title": "Key ID", + "description": "The ID of this JWK" + }, + "use": { + "type": "string", + "enum": [ + "sig" + ], + "title": "Use", + "description": "The Use of this JWK", + "default": "sig" + }, + "algorithm": { + "type": "string", + "enum": [ + "HS256", + "HS384", + "HS512", + "RS256", + "RS384", + "RS512", + "ES256", + "ES384", + "ES512", + "PS256", + "PS384", + "PS512" + ], + "title": "Algorithm", + "description": "The Algorithm of this JWK" + }, + "key": { + "type": "string", + "description": "The Private/Public key material of this JWK in Base64 PEM format" + }, + "certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Certificate Chain", + "description": "The optional associated certificate which matches the Key public key portion for this JWK" + } + }, + "additionalProperties": false, + "type": "object", + "description": "JWK represents a JWK." + }, + "Log": { + "properties": { + "level": { + "type": "string", + "enum": [ + "error", + "warn", + "info", + "debug", + "trace" + ], + "title": "Level", + "description": "The minimum Level a Log message must be before it's added to the log'" + }, + "format": { + "type": "string", + "enum": [ + "json", + "text" + ], + "title": "Format", + "description": "The Format of Log messages" + }, + "file_path": { + "type": "string", + "title": "File Path", + "description": "The File Path to save the logs to instead of sending them to stdout" + }, + "keep_stdout": { + "type": "boolean", + "title": "Keep Stdout", + "description": "Enables keeping stdout when using the File Path option", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "Log represents the logging configuration." + }, + "NTP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressUDP" + }, + "version": { + "type": "integer", + "enum": [ + 3, + 4 + ], + "title": "NTP Version", + "description": "The NTP Version to use" + }, + "max_desync": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Maximum Desync", + "description": "The maximum amount of time that the server can be out of sync" + }, + "disable_startup_check": { + "type": "boolean", + "title": "Disable Startup Check", + "description": "Disables the NTP Startup Check entirely", + "default": false + }, + "disable_failure": { + "type": "boolean", + "title": "Disable Failure", + "description": "Disables complete failure whe the Startup Check fails and instead just logs the error", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "NTP represents the configuration related to ntp server." + }, + "Notifier": { + "properties": { + "disable_startup_check": { + "type": "boolean", + "title": "Disable Startup Check", + "description": "Disables the notifier startup checks", + "default": false + }, + "filesystem": { + "$ref": "#/$defs/NotifierFileSystem", + "title": "File System", + "description": "The File System notifier" + }, + "smtp": { + "$ref": "#/$defs/NotifierSMTP", + "title": "SMTP", + "description": "The SMTP notifier" + }, + "template_path": { + "type": "string", + "title": "Template Path", + "description": "The path for notifier template overrides" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Notifier represents the configuration of the notifier to use when sending notifications to users." + }, + "NotifierFileSystem": { + "properties": { + "filename": { + "type": "string", + "title": "Filename", + "description": "The file path of the notifications" + } + }, + "additionalProperties": false, + "type": "object", + "description": "NotifierFileSystem represents the configuration of the notifier writing emails in a file." + }, + "NotifierSMTP": { + "properties": { + "address": { + "$ref": "#/$defs/AddressSMTP", + "title": "Address", + "description": "The SMTP server address" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The SMTP server connection timeout" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username for SMTP authentication" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password for SMTP authentication" + }, + "identifier": { + "type": "string", + "title": "Identifier", + "description": "The identifier used during the HELO/EHLO command", + "default": "localhost" + }, + "sender": { + "oneOf": [ + { + "type": "string", + "pattern": "^[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$" + }, + { + "type": "string", + "pattern": "^[^\u003c]+ \u003c[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*\u003e$" + } + ], + "title": "Sender", + "description": "The sender used for SMTP" + }, + "subject": { + "type": "string", + "title": "Subject", + "description": "The subject format used", + "default": "[Authelia] {title}" + }, + "startup_check_address": { + "oneOf": [ + { + "type": "string", + "pattern": "^[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$" + }, + { + "type": "string", + "pattern": "^[^\u003c]+ \u003c[a-zA-Z0-9.!#$%\u0026'*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*\u003e$" + } + ], + "title": "Startup Check Address", + "description": "The address used for the recipient in the startup check" + }, + "disable_require_tls": { + "type": "boolean", + "title": "Disable Require TLS", + "description": "Disables the requirement to use TLS", + "default": false + }, + "disable_html_emails": { + "type": "boolean", + "title": "Disable HTML Emails", + "description": "Disables the mixed content type of emails and only sends the plaintext version", + "default": false + }, + "disable_starttls": { + "type": "boolean", + "title": "Disable StartTLS", + "description": "Disables the opportunistic StartTLS functionality which is useful for bad SMTP servers which advertise support for it but don't actually support it'", + "default": false + }, + "tls": { + "$ref": "#/$defs/TLS", + "title": "TLS", + "description": "The SMTP server TLS connection properties" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "NotifierSMTP represents the configuration of the SMTP server to send emails with." + }, + "PasswordDigest": { + "type": "string", + "pattern": "^\\$((argon2(id|i|d)\\$v=19\\$m=\\d+,t=\\d+,p=\\d+|scrypt\\$ln=\\d+,r=\\d+,p=\\d+)\\$[a-zA-Z0-9\\/+]+\\$[a-zA-Z0-9\\/+]+|pbkdf2(-sha(224|256|384|512))?\\$\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|bcrypt-sha256\\$v=2,t=2b,r=\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|2(a|b|y)?\\$\\d+\\$[a-zA-Z0-9.\\/]+|(5|6)\\$rounds=\\d+\\$[a-zA-Z0-9.\\/]+\\$[a-zA-Z0-9.\\/]+|plaintext\\$.+|base64\\$[a-zA-Z0-9.=\\/]+)$" + }, + "PasswordPolicy": { + "properties": { + "standard": { + "$ref": "#/$defs/PasswordPolicyStandard", + "title": "Standard", + "description": "The standard password policy engine" + }, + "zxcvbn": { + "$ref": "#/$defs/PasswordPolicyZXCVBN", + "title": "ZXCVBN", + "description": "The ZXCVBN password policy engine" + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicy represents the configuration related to password policy." + }, + "PasswordPolicyStandard": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the standard password policy engine", + "default": false + }, + "min_length": { + "type": "integer", + "title": "Minimum Length", + "description": "Minimum password length" + }, + "max_length": { + "type": "integer", + "title": "Maximum Length", + "description": "Maximum password length", + "default": 8 + }, + "require_uppercase": { + "type": "boolean", + "title": "Require Uppercase", + "description": "Require uppercase characters", + "default": false + }, + "require_lowercase": { + "type": "boolean", + "title": "Require Lowercase", + "description": "Require lowercase characters", + "default": false + }, + "require_number": { + "type": "boolean", + "title": "Require Number", + "description": "Require numeric characters", + "default": false + }, + "require_special": { + "type": "boolean", + "title": "Require Special", + "description": "Require symbolic characters", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicyStandard represents the configuration related to standard parameters of password policy." + }, + "PasswordPolicyZXCVBN": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the ZXCVBN password policy engine", + "default": false + }, + "min_score": { + "type": "integer", + "title": "Minimum Score", + "description": "The minimum ZXCVBN score allowed", + "default": 3 + } + }, + "additionalProperties": false, + "type": "object", + "description": "PasswordPolicyZXCVBN represents the configuration related to ZXCVBN parameters of password policy." + }, + "PrivacyPolicy": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the Privacy Policy functionality", + "default": false + }, + "require_user_acceptance": { + "type": "boolean", + "title": "Require User Acceptance", + "description": "Enables the requirement for users to accept the policy", + "default": false + }, + "policy_url": { + "type": "string", + "format": "uri", + "title": "Policy URL", + "description": "The URL of the privacy policy" + } + }, + "additionalProperties": false, + "type": "object", + "description": "PrivacyPolicy is the privacy policy configuration." + }, + "Regulation": { + "properties": { + "max_retries": { + "type": "integer", + "title": "Maximum Retries", + "description": "The maximum number of failed attempts permitted before banning a user", + "default": 3 + }, + "find_time": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Find Time", + "description": "The amount of time to consider when determining the number of failed attempts" + }, + "ban_time": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Ban Time", + "description": "The amount of time to ban the user for when it's determined the maximum retries has been exceeded'" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Regulation represents the configuration related to regulation." + }, + "Server": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address to listen on" + }, + "asset_path": { + "type": "string", + "title": "Asset Path", + "description": "The directory where the server asset overrides reside" + }, + "disable_healthcheck": { + "type": "boolean", + "title": "Disable Healthcheck", + "description": "Disables the healthcheck functionality", + "default": false + }, + "tls": { + "$ref": "#/$defs/ServerTLS", + "title": "TLS", + "description": "The server TLS configuration" + }, + "headers": { + "$ref": "#/$defs/ServerHeaders", + "title": "Headers", + "description": "The server headers configuration" + }, + "endpoints": { + "$ref": "#/$defs/ServerEndpoints", + "title": "Endpoints", + "description": "The server endpoints configuration" + }, + "buffers": { + "$ref": "#/$defs/ServerBuffers", + "title": "Buffers", + "description": "The server buffers configuration" + }, + "timeouts": { + "$ref": "#/$defs/ServerTimeouts", + "title": "Timeouts", + "description": "The server timeouts configuration" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "path": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Server represents the configuration of the http server." + }, + "ServerBuffers": { + "properties": { + "read": { + "type": "integer", + "title": "Read", + "description": "The read buffer size", + "default": 4096 + }, + "write": { + "type": "integer", + "title": "Write", + "description": "The write buffer size", + "default": 4096 + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerBuffers represents server buffer configurations." + }, + "ServerEndpoints": { + "properties": { + "enable_pprof": { + "type": "boolean", + "title": "Enable PProf", + "description": "Enables the developer specific pprof endpoints which should not be used in production and only used for debugging purposes", + "default": false + }, + "enable_expvars": { + "type": "boolean", + "title": "Enable ExpVars", + "description": "Enables the developer specific ExpVars endpoints which should not be used in production and only used for debugging purposes", + "default": false + }, + "authz": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/ServerEndpointsAuthz" + } + }, + "type": "object", + "title": "Authz", + "description": "Configures the Authorization endpoints" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpoints is the endpoints configuration for the HTTP server." + }, + "ServerEndpointsAuthz": { + "properties": { + "implementation": { + "type": "string", + "enum": [ + "ForwardAuth", + "AuthRequest", + "ExtAuthz", + "Legacy" + ], + "title": "Implementation", + "description": "The specific Authorization implementation to use for this endpoint" + }, + "authn_strategies": { + "items": { + "$ref": "#/$defs/ServerEndpointsAuthzAuthnStrategy" + }, + "type": "array", + "title": "Authn Strategies", + "description": "The specific Authorization strategies to use for this endpoint" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpointsAuthz is the Authz endpoints configuration for the HTTP server." + }, + "ServerEndpointsAuthzAuthnStrategy": { + "properties": { + "name": { + "type": "string", + "enum": [ + "HeaderAuthorization", + "HeaderProxyAuthorization", + "HeaderAuthRequestProxyAuthorization", + "HeaderLegacy", + "CookieSession" + ], + "title": "Name", + "description": "The name of the Authorization strategy to use" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerEndpointsAuthzAuthnStrategy is the Authz endpoints configuration for the HTTP server." + }, + "ServerHeaders": { + "properties": { + "csp_template": { + "type": "string", + "title": "CSP Template", + "description": "The Content Security Policy template", + "default": "default-src 'self'; frame-src 'none'; object-src 'none'; style-src 'self' 'nonce-%s'; frame-ancestors 'none'; base-uri 'self'" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerHeaders represents the customization of the http server headers." + }, + "ServerTLS": { + "properties": { + "certificate": { + "type": "string", + "title": "Certificate", + "description": "Path to the Certificate" + }, + "key": { + "type": "string", + "title": "Key", + "description": "Path to the Private Key" + }, + "client_certificates": { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true, + "title": "Client Certificates", + "description": "Path to the Client Certificates to trust for mTLS" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerTLS represents the configuration of the http servers TLS options." + }, + "ServerTimeouts": { + "properties": { + "read": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Read", + "description": "The read timeout" + }, + "write": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Write", + "description": "The write timeout" + }, + "idle": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Idle", + "description": "The idle timeout" + } + }, + "additionalProperties": false, + "type": "object", + "description": "ServerTimeouts represents server timeout configurations." + }, + "Session": { + "properties": { + "name": { + "type": "string", + "default": "authelia_session" + }, + "same_site": { + "type": "string", + "enum": [ + "lax", + "strict", + "none" + ], + "default": "lax" + }, + "expiration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "inactivity": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "remember_me": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "DisableRememberMe": { + "type": "boolean" + }, + "secret": { + "type": "string", + "title": "Secret", + "description": "Secret used to encrypt the session data" + }, + "cookies": { + "items": { + "$ref": "#/$defs/SessionCookie" + }, + "type": "array", + "title": "Cookies", + "description": "List of cookie domain configurations" + }, + "redis": { + "$ref": "#/$defs/SessionRedis", + "title": "Redis", + "description": "Redis Session Provider configuration" + }, + "domain": { + "type": "string", + "description": "Deprecated: Use the cookies options instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Session represents the configuration related to user sessions." + }, + "SessionCookie": { + "properties": { + "name": { + "type": "string", + "default": "authelia_session" + }, + "same_site": { + "type": "string", + "enum": [ + "lax", + "strict", + "none" + ], + "default": "lax" + }, + "expiration": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "inactivity": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "remember_me": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ] + }, + "DisableRememberMe": { + "type": "boolean" + }, + "domain": { + "type": "string", + "format": "hostname", + "title": "Domain", + "description": "The domain for this session cookie" + }, + "authelia_url": { + "type": "string", + "format": "uri", + "title": "Authelia URL", + "description": "The Root Authelia URL to redirect users to for this session cookie" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionCookie represents the configuration for a cookie domain." + }, + "SessionRedis": { + "properties": { + "host": { + "type": "string", + "title": "Host", + "description": "The redis server host" + }, + "port": { + "type": "integer", + "title": "Host", + "description": "The redis server port", + "default": 6379 + }, + "username": { + "type": "string", + "title": "Username", + "description": "The redis username" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The redis password" + }, + "database_index": { + "type": "integer", + "title": "Database Index", + "description": "The redis database index", + "default": 0 + }, + "maximum_active_connections": { + "type": "integer", + "title": "Maximum Active Connections", + "description": "The maximum connections that can be made to redis at one time", + "default": 8 + }, + "minimum_idle_connections": { + "type": "integer", + "title": "Minimum Idle Connections", + "description": "The minimum idle connections that should be open to redis" + }, + "tls": { + "$ref": "#/$defs/TLS" + }, + "high_availability": { + "$ref": "#/$defs/SessionRedisHighAvailability" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedis represents the configuration related to redis session store." + }, + "SessionRedisHighAvailability": { + "properties": { + "sentinel_name": { + "type": "string", + "title": "Sentinel Name", + "description": "The name of the sentinel instance" + }, + "sentinel_username": { + "type": "string", + "title": "Sentinel Username", + "description": "The username for the sentinel instance" + }, + "sentinel_password": { + "type": "string", + "title": "Sentinel Username", + "description": "The username for the sentinel instance" + }, + "route_by_latency": { + "type": "boolean", + "title": "Route by Latency", + "description": "Uses the Route by Latency mode", + "default": false + }, + "route_randomly": { + "type": "boolean", + "title": "Route Randomly", + "description": "Uses the Route Randomly mode", + "default": false + }, + "nodes": { + "items": { + "$ref": "#/$defs/SessionRedisHighAvailabilityNode" + }, + "type": "array", + "title": "Nodes", + "description": "The pre-populated list of nodes for the sentinel instance" + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedisHighAvailability holds configuration variables for Redis Cluster/Sentinel." + }, + "SessionRedisHighAvailabilityNode": { + "properties": { + "host": { + "type": "string", + "title": "Host", + "description": "The redis sentinel node host" + }, + "port": { + "type": "integer", + "title": "Port", + "description": "The redis sentinel node port", + "default": 26379 + } + }, + "additionalProperties": false, + "type": "object", + "description": "SessionRedisHighAvailabilityNode Represents a Node." + }, + "Storage": { + "properties": { + "local": { + "$ref": "#/$defs/StorageLocal", + "title": "Local", + "description": "The Local SQLite3 Storage configuration settings" + }, + "mysql": { + "$ref": "#/$defs/StorageMySQL", + "title": "MySQL", + "description": "The MySQL/MariaDB Storage configuration settings" + }, + "postgres": { + "$ref": "#/$defs/StoragePostgreSQL", + "title": "PostgreSQL", + "description": "The PostgreSQL Storage configuration settings" + }, + "encryption_key": { + "type": "string", + "title": "Encryption Key", + "description": "The Storage Encryption Key used to secure security sensitive values in the storage engine" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Storage represents the configuration of the storage backend." + }, + "StorageLocal": { + "properties": { + "path": { + "type": "string", + "title": "Path", + "description": "The Path for the SQLite3 database file" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StorageLocal represents the configuration when using local storage." + }, + "StorageMySQL": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address of the database" + }, + "database": { + "type": "string", + "title": "Database", + "description": "The database name to use upon a successful connection" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username to use to authenticate" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password to use to authenticate" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The timeout for the database connection" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "tls": { + "$ref": "#/$defs/TLS" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StorageMySQL represents the configuration of a MySQL database." + }, + "StoragePostgreSQL": { + "properties": { + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address of the database" + }, + "database": { + "type": "string", + "title": "Database", + "description": "The database name to use upon a successful connection" + }, + "username": { + "type": "string", + "title": "Username", + "description": "The username to use to authenticate" + }, + "password": { + "type": "string", + "title": "Password", + "description": "The password to use to authenticate" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The timeout for the database connection" + }, + "host": { + "type": "string", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "port": { + "type": "integer", + "description": "Deprecated: use address instead.", + "deprecated": true + }, + "schema": { + "type": "string", + "default": "public" + }, + "tls": { + "$ref": "#/$defs/TLS" + }, + "ssl": { + "$ref": "#/$defs/StoragePostgreSQLSSL", + "description": "Deprecated: Use the TLS configuration instead.", + "deprecated": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "StoragePostgreSQL represents the configuration of a PostgreSQL database." + }, + "StoragePostgreSQLSSL": { + "properties": { + "mode": { + "type": "string", + "deprecated": true + }, + "root_certificate": { + "type": "string", + "deprecated": true + }, + "certificate": { + "type": "string", + "deprecated": true + }, + "key": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "description": "StoragePostgreSQLSSL represents the SSL configuration of a PostgreSQL database." + }, + "TLS": { + "properties": { + "minimum_version": { + "$ref": "#/$defs/TLSVersion", + "title": "Minimum Version", + "description": "The minimum TLS version accepted" + }, + "maximum_version": { + "$ref": "#/$defs/TLSVersion", + "title": "Maximum Version", + "description": "The maximum TLS version accepted" + }, + "skip_verify": { + "type": "boolean", + "title": "Skip Verify", + "description": "Disable all verification of the TLS properties", + "default": false + }, + "server_name": { + "type": "string", + "format": "hostname", + "title": "Server Name", + "description": "The expected server name to match the certificate against" + }, + "private_key": { + "type": "string", + "pattern": "^-{5}(BEGIN ((RSA|EC) )?PRIVATE KEY-{5}\\n([a-zA-Z0-9/+]{1,64}\\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\\n-{5}END ((RSA|EC) )?PRIVATE KEY-{5}\\n?)+$", + "title": "Private Key", + "description": "The private key" + }, + "certificate_chain": { + "$ref": "#/$defs/X509CertificateChain", + "title": "Certificate Chain", + "description": "The certificate chain" + } + }, + "additionalProperties": false, + "type": "object", + "description": "TLS is a representation of the TLS configuration." + }, + "TLSVersion": { + "type": "string", + "enum": [ + "TLS1.0", + "TLS1.1", + "TLS1.2", + "TLS1.3" + ] + }, + "TOTP": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the TOTP 2FA functionality", + "default": false + }, + "issuer": { + "type": "string", + "title": "Issuer", + "description": "The issuer value for generated TOTP keys", + "default": "Authelia" + }, + "algorithm": { + "type": "string", + "enum": [ + "SHA1", + "SHA256", + "SHA512" + ], + "title": "Algorithm", + "description": "The algorithm value for generated TOTP keys", + "default": "SHA1" + }, + "digits": { + "type": "integer", + "enum": [ + 6, + 8 + ], + "title": "Digits", + "description": "The digits value for generated TOTP keys", + "default": 6 + }, + "period": { + "type": "integer", + "title": "Period", + "description": "The period value for generated TOTP keys", + "default": 30 + }, + "skew": { + "type": "integer", + "title": "Skew", + "description": "The permitted skew for generated TOTP keys", + "default": 1 + }, + "secret_size": { + "type": "integer", + "minimum": 20, + "title": "Secret Size", + "description": "The secret size for generated TOTP keys", + "default": 32 + } + }, + "additionalProperties": false, + "type": "object", + "description": "TOTP represents the configuration related to TOTP options." + }, + "Telemetry": { + "properties": { + "metrics": { + "$ref": "#/$defs/TelemetryMetrics", + "title": "Metrics", + "description": "The telemetry metrics server configuration" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Telemetry represents the telemetry config." + }, + "TelemetryMetrics": { + "properties": { + "enabled": { + "type": "boolean", + "title": "Enabled", + "description": "Enables the metrics server", + "default": false + }, + "address": { + "$ref": "#/$defs/AddressTCP", + "title": "Address", + "description": "The address for the metrics server to listen on" + }, + "buffers": { + "$ref": "#/$defs/ServerBuffers", + "title": "Buffers", + "description": "The server buffers configuration for the metrics server" + }, + "timeouts": { + "$ref": "#/$defs/ServerTimeouts", + "title": "Timeouts", + "description": "The server timeouts configuration for the metrics server" + } + }, + "additionalProperties": false, + "type": "object", + "description": "TelemetryMetrics represents the telemetry metrics config." + }, + "WebAuthn": { + "properties": { + "disable": { + "type": "boolean", + "title": "Disable", + "description": "Disables the WebAuthn 2FA functionality", + "default": false + }, + "display_name": { + "type": "string", + "title": "Display Name", + "description": "The display name attribute for the WebAuthn relying party", + "default": "Authelia" + }, + "attestation_conveyance_preference": { + "type": "string", + "enum": [ + "none", + "indirect", + "direct" + ], + "title": "Conveyance Preference", + "description": "The default conveyance preference for all WebAuthn credentials", + "default": "indirect" + }, + "user_verification": { + "type": "string", + "enum": [ + "discouraged", + "preferred", + "required" + ], + "title": "User Verification", + "description": "The default user verification preference for all WebAuthn credentials", + "default": "preferred" + }, + "timeout": { + "oneOf": [ + { + "$comment": "Example comment", + "type": "string", + "pattern": "^\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?))(\\s*\\d+\\s*(y|M|w|d|h|m|s|ms|((year|month|week|day|hour|minute|second|millisecond)s?)))*$" + }, + { + "type": "integer", + "description": "The duration in seconds" + } + ], + "title": "Timeout", + "description": "The default timeout for all WebAuthn ceremonies" + } + }, + "additionalProperties": false, + "type": "object", + "description": "WebAuthn represents the webauthn config." + }, + "X509CertificateChain": { + "type": "string", + "pattern": "^(-{5}BEGIN CERTIFICATE-{5}\\n([a-zA-Z0-9/+]{1,64}\\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\\n-{5}END CERTIFICATE-{5}\\n?)+$" + } + } +} \ No newline at end of file diff --git a/docs/static/schemas/v4.38/user-database.json b/docs/static/schemas/v4.38/user-database.json new file mode 100644 index 000000000..51853c6ae --- /dev/null +++ b/docs/static/schemas/v4.38/user-database.json @@ -0,0 +1,71 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.authelia.com/v4.38/json-schema/user-database.json", + "$ref": "#/$defs/FileUserDatabase", + "$defs": { + "FileUserDatabase": { + "properties": { + "users": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/FileUserDatabaseUserDetails" + } + }, + "type": "object", + "title": "Users", + "description": "The dictionary of users" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "users" + ], + "description": "FileUserDatabase is a user details database that is concurrency safe database and can be reloaded." + }, + "FileUserDatabaseUserDetails": { + "properties": { + "password": { + "$ref": "#/$defs/PasswordDigest", + "title": "Password", + "description": "The hashed password for the user" + }, + "displayname": { + "type": "string", + "title": "Display Name", + "description": "The display name for the user" + }, + "email": { + "type": "string", + "title": "Email", + "description": "The email for the user" + }, + "groups": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Groups", + "description": "The groups list for the user" + }, + "disabled": { + "type": "boolean", + "title": "Disabled", + "description": "The disabled status for the user", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "password", + "displayname" + ], + "description": "FileUserDatabaseUserDetails is the model of user details in the file database." + }, + "PasswordDigest": { + "type": "string", + "pattern": "^\\$((argon2(id|i|d)\\$v=19\\$m=\\d+,t=\\d+,p=\\d+|scrypt\\$ln=\\d+,r=\\d+,p=\\d+)\\$[a-zA-Z0-9\\/+]+\\$[a-zA-Z0-9\\/+]+|pbkdf2(-sha(224|256|384|512))?\\$\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|bcrypt-sha256\\$v=2,t=2b,r=\\d+\\$[a-zA-Z0-9\\/.]+\\$[a-zA-Z0-9\\/.]+|2(a|b|y)?\\$\\d+\\$[a-zA-Z0-9.\\/]+|(5|6)\\$rounds=\\d+\\$[a-zA-Z0-9.\\/]+\\$[a-zA-Z0-9.\\/]+|plaintext\\$.+|base64\\$[a-zA-Z0-9.=\\/]+)$" + } + } +} \ No newline at end of file diff --git a/go.mod b/go.mod index d225a03f6..911d57ee6 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d + github.com/authelia/jsonschema v0.1.4 github.com/deckarep/golang-set/v2 v2.3.0 github.com/duosecurity/duo_api_golang v0.0.0-20230418202038-096d3306c029 github.com/fasthttp/router v1.4.19 @@ -79,6 +80,7 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/iancoleman/orderedmap v0.2.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect diff --git a/go.sum b/go.sum index 813c04b7f..e5359b281 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,14 @@ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/authelia/jsonschema v0.1.1 h1:gxCH8wbKYky29y7uSDe4CF17J1wcJTdVi4EQACmj3D4= +github.com/authelia/jsonschema v0.1.1/go.mod h1:v8XIVOs8fPffQr+9HPT2HJxlvD/Miwyss4petlzUOxk= +github.com/authelia/jsonschema v0.1.2 h1:Mf6PoYj+nvYoAaaCaQIPcqEPli4a4GaDAzA6Gw/bqac= +github.com/authelia/jsonschema v0.1.2/go.mod h1:v8XIVOs8fPffQr+9HPT2HJxlvD/Miwyss4petlzUOxk= +github.com/authelia/jsonschema v0.1.3 h1:O4xzeGm81zs7/5oW6p4k12INxUFDpHRd89thIcLirqQ= +github.com/authelia/jsonschema v0.1.3/go.mod h1:v8XIVOs8fPffQr+9HPT2HJxlvD/Miwyss4petlzUOxk= +github.com/authelia/jsonschema v0.1.4 h1:aSqM2lbZ0yUSRXy+tKe1RsLF1q56aclxSe/TG9y3zk0= +github.com/authelia/jsonschema v0.1.4/go.mod h1:v8XIVOs8fPffQr+9HPT2HJxlvD/Miwyss4petlzUOxk= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -247,6 +255,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= +github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= diff --git a/internal/authentication/file_user_provider.go b/internal/authentication/file_user_provider.go index bf63fd3fd..ad7f204aa 100644 --- a/internal/authentication/file_user_provider.go +++ b/internal/authentication/file_user_provider.go @@ -21,20 +21,20 @@ import ( // FileUserProvider is a provider reading details from a file. type FileUserProvider struct { - config *schema.FileAuthenticationBackend + config *schema.AuthenticationBackendFile hash algorithm.Hash - database FileUserDatabase + database FileUserProviderDatabase mutex *sync.Mutex timeoutReload time.Time } // NewFileUserProvider creates a new instance of FileUserProvider. -func NewFileUserProvider(config *schema.FileAuthenticationBackend) (provider *FileUserProvider) { +func NewFileUserProvider(config *schema.AuthenticationBackendFile) (provider *FileUserProvider) { return &FileUserProvider{ config: config, mutex: &sync.Mutex{}, timeoutReload: time.Now().Add(-1 * time.Second), - database: NewYAMLUserDatabase(config.Path, config.Search.Email, config.Search.CaseInsensitive), + database: NewFileUserDatabase(config.Path, config.Search.Email, config.Search.CaseInsensitive), } } @@ -66,7 +66,7 @@ func (p *FileUserProvider) Reload() (reloaded bool, err error) { // CheckUserPassword checks if provided password matches for the given user. func (p *FileUserProvider) CheckUserPassword(username string, password string) (match bool, err error) { - var details DatabaseUserDetails + var details FileUserDatabaseUserDetails if details, err = p.database.GetUserDetails(username); err != nil { return false, err @@ -76,12 +76,12 @@ func (p *FileUserProvider) CheckUserPassword(username string, password string) ( return false, ErrUserNotFound } - return details.Digest.MatchAdvanced(password) + return details.Password.MatchAdvanced(password) } // GetDetails retrieve the groups a user belongs to. func (p *FileUserProvider) GetDetails(username string) (details *UserDetails, err error) { - var d DatabaseUserDetails + var d FileUserDatabaseUserDetails if d, err = p.database.GetUserDetails(username); err != nil { return nil, err @@ -96,7 +96,7 @@ func (p *FileUserProvider) GetDetails(username string) (details *UserDetails, er // UpdatePassword update the password of the given user. func (p *FileUserProvider) UpdatePassword(username string, newPassword string) (err error) { - var details DatabaseUserDetails + var details FileUserDatabaseUserDetails if details, err = p.database.GetUserDetails(username); err != nil { return err @@ -106,10 +106,14 @@ func (p *FileUserProvider) UpdatePassword(username string, newPassword string) ( return ErrUserNotFound } - if details.Digest, err = p.hash.Hash(newPassword); err != nil { + var digest algorithm.Digest + + if digest, err = p.hash.Hash(newPassword); err != nil { return err } + details.Password = schema.NewPasswordDigest(digest) + p.database.SetUserDetails(details.Username, &details) p.mutex.Lock() @@ -138,7 +142,7 @@ func (p *FileUserProvider) StartupCheck() (err error) { } if p.database == nil { - p.database = NewYAMLUserDatabase(p.config.Path, p.config.Search.Email, p.config.Search.CaseInsensitive) + p.database = NewFileUserDatabase(p.config.Path, p.config.Search.Email, p.config.Search.CaseInsensitive) } if err = p.database.Load(); err != nil { @@ -153,7 +157,7 @@ func (p *FileUserProvider) setTimeoutReload(now time.Time) { } // NewFileCryptoHashFromConfig returns a crypt.Hash given a valid configuration. -func NewFileCryptoHashFromConfig(config schema.Password) (hash algorithm.Hash, err error) { +func NewFileCryptoHashFromConfig(config schema.AuthenticationBackendFilePassword) (hash algorithm.Hash, err error) { switch config.Algorithm { case hashArgon2, "": hash, err = argon2.New( diff --git a/internal/authentication/file_user_provider_database.go b/internal/authentication/file_user_provider_database.go index f5c526096..5a802b1bb 100644 --- a/internal/authentication/file_user_provider_database.go +++ b/internal/authentication/file_user_provider_database.go @@ -10,21 +10,23 @@ import ( "github.com/go-crypt/crypt" "github.com/go-crypt/crypt/algorithm" "gopkg.in/yaml.v3" + + "github.com/authelia/authelia/v4/internal/configuration/schema" ) -type FileUserDatabase interface { +type FileUserProviderDatabase interface { Save() (err error) Load() (err error) - GetUserDetails(username string) (user DatabaseUserDetails, err error) - SetUserDetails(username string, details *DatabaseUserDetails) + GetUserDetails(username string) (user FileUserDatabaseUserDetails, err error) + SetUserDetails(username string, details *FileUserDatabaseUserDetails) } -// NewYAMLUserDatabase creates a new YAMLUserDatabase. -func NewYAMLUserDatabase(filePath string, searchEmail, searchCI bool) (database *YAMLUserDatabase) { - return &YAMLUserDatabase{ +// NewFileUserDatabase creates a new FileUserDatabase. +func NewFileUserDatabase(filePath string, searchEmail, searchCI bool) (database *FileUserDatabase) { + return &FileUserDatabase{ RWMutex: &sync.RWMutex{}, Path: filePath, - Users: map[string]DatabaseUserDetails{}, + Users: map[string]FileUserDatabaseUserDetails{}, Emails: map[string]string{}, Aliases: map[string]string{}, SearchEmail: searchEmail, @@ -32,21 +34,22 @@ func NewYAMLUserDatabase(filePath string, searchEmail, searchCI bool) (database } } -// YAMLUserDatabase is a user details database that is concurrency safe database and can be reloaded. -type YAMLUserDatabase struct { - *sync.RWMutex +// FileUserDatabase is a user details database that is concurrency safe database and can be reloaded. +type FileUserDatabase struct { + *sync.RWMutex `json:"-"` - Path string - Users map[string]DatabaseUserDetails - Emails map[string]string - Aliases map[string]string + Users map[string]FileUserDatabaseUserDetails `json:"users" jsonschema:"required,title=Users" jsonschema_description:"The dictionary of users"` - SearchEmail bool - SearchCI bool + Path string `json:"-"` + Emails map[string]string `json:"-"` + Aliases map[string]string `json:"-"` + + SearchEmail bool `json:"-"` + SearchCI bool `json:"-"` } // Save the database to disk. -func (m *YAMLUserDatabase) Save() (err error) { +func (m *FileUserDatabase) Save() (err error) { m.RLock() defer m.RUnlock() @@ -59,8 +62,8 @@ func (m *YAMLUserDatabase) Save() (err error) { } // Load the database from disk. -func (m *YAMLUserDatabase) Load() (err error) { - yml := &DatabaseModel{Users: map[string]UserDetailsModel{}} +func (m *FileUserDatabase) Load() (err error) { + yml := &FileDatabaseModel{Users: map[string]FileDatabaseUserDetailsModel{}} if err = yml.Read(m.Path); err != nil { return fmt.Errorf("error reading the authentication database: %w", err) @@ -78,7 +81,7 @@ func (m *YAMLUserDatabase) Load() (err error) { } // LoadAliases performs the loading of alias information from the database. -func (m *YAMLUserDatabase) LoadAliases() (err error) { +func (m *FileUserDatabase) LoadAliases() (err error) { if m.SearchEmail || m.SearchCI { for k, user := range m.Users { if m.SearchEmail && user.Email != "" { @@ -98,7 +101,7 @@ func (m *YAMLUserDatabase) LoadAliases() (err error) { return nil } -func (m *YAMLUserDatabase) loadAlias(k string) (err error) { +func (m *FileUserDatabase) loadAlias(k string) (err error) { u := strings.ToLower(k) if u != k { @@ -120,7 +123,7 @@ func (m *YAMLUserDatabase) loadAlias(k string) (err error) { return nil } -func (m *YAMLUserDatabase) loadAliasEmail(k string, user DatabaseUserDetails) (err error) { +func (m *FileUserDatabase) loadAliasEmail(k string, user FileUserDatabaseUserDetails) (err error) { e := strings.ToLower(user.Email) var duplicates []string @@ -150,9 +153,9 @@ func (m *YAMLUserDatabase) loadAliasEmail(k string, user DatabaseUserDetails) (e return nil } -// GetUserDetails get a DatabaseUserDetails given a username as a value type where the username must be the users actual +// GetUserDetails get a FileUserDatabaseUserDetails given a username as a value type where the username must be the users actual // username. -func (m *YAMLUserDatabase) GetUserDetails(username string) (user DatabaseUserDetails, err error) { +func (m *FileUserDatabase) GetUserDetails(username string) (user FileUserDatabaseUserDetails, err error) { m.RLock() defer m.RUnlock() @@ -178,8 +181,8 @@ func (m *YAMLUserDatabase) GetUserDetails(username string) (user DatabaseUserDet return user, ErrUserNotFound } -// SetUserDetails sets the DatabaseUserDetails for a given user. -func (m *YAMLUserDatabase) SetUserDetails(username string, details *DatabaseUserDetails) { +// SetUserDetails sets the FileUserDatabaseUserDetails for a given user. +func (m *FileUserDatabase) SetUserDetails(username string, details *FileUserDatabaseUserDetails) { if details == nil { return } @@ -191,10 +194,10 @@ func (m *YAMLUserDatabase) SetUserDetails(username string, details *DatabaseUser m.Unlock() } -// ToDatabaseModel converts the YAMLUserDatabase into the DatabaseModel for saving. -func (m *YAMLUserDatabase) ToDatabaseModel() (model *DatabaseModel) { - model = &DatabaseModel{ - Users: map[string]UserDetailsModel{}, +// ToDatabaseModel converts the FileUserDatabase into the FileDatabaseModel for saving. +func (m *FileUserDatabase) ToDatabaseModel() (model *FileDatabaseModel) { + model = &FileDatabaseModel{ + Users: map[string]FileDatabaseUserDetailsModel{}, } m.RLock() @@ -208,18 +211,18 @@ func (m *YAMLUserDatabase) ToDatabaseModel() (model *DatabaseModel) { return model } -// DatabaseUserDetails is the model of user details in the file database. -type DatabaseUserDetails struct { - Username string - Digest algorithm.Digest - Disabled bool - DisplayName string - Email string - Groups []string +// FileUserDatabaseUserDetails is the model of user details in the file database. +type FileUserDatabaseUserDetails struct { + Username string `json:"-"` + Password *schema.PasswordDigest `json:"password" jsonschema:"required,title=Password" jsonschema_description:"The hashed password for the user"` + DisplayName string `json:"displayname" jsonschema:"required,title=Display Name" jsonschema_description:"The display name for the user"` + Email string `json:"email" jsonschema:"title=Email" jsonschema_description:"The email for the user"` + Groups []string `json:"groups" jsonschema:"title=Groups" jsonschema_description:"The groups list for the user"` + Disabled bool `json:"disabled" jsonschema:"default=false,title=Disabled" jsonschema_description:"The disabled status for the user"` } -// ToUserDetails converts DatabaseUserDetails into a *UserDetails given a username. -func (m DatabaseUserDetails) ToUserDetails() (details *UserDetails) { +// ToUserDetails converts FileUserDatabaseUserDetails into a *UserDetails given a username. +func (m FileUserDatabaseUserDetails) ToUserDetails() (details *UserDetails) { return &UserDetails{ Username: m.Username, DisplayName: m.DisplayName, @@ -228,26 +231,26 @@ func (m DatabaseUserDetails) ToUserDetails() (details *UserDetails) { } } -// ToUserDetailsModel converts DatabaseUserDetails into a UserDetailsModel. -func (m DatabaseUserDetails) ToUserDetailsModel() (model UserDetailsModel) { - return UserDetailsModel{ - HashedPassword: m.Digest.Encode(), - DisplayName: m.DisplayName, - Email: m.Email, - Groups: m.Groups, +// ToUserDetailsModel converts FileUserDatabaseUserDetails into a FileDatabaseUserDetailsModel. +func (m FileUserDatabaseUserDetails) ToUserDetailsModel() (model FileDatabaseUserDetailsModel) { + return FileDatabaseUserDetailsModel{ + Password: m.Password.Encode(), + DisplayName: m.DisplayName, + Email: m.Email, + Groups: m.Groups, } } -// DatabaseModel is the model of users file database. -type DatabaseModel struct { - Users map[string]UserDetailsModel `yaml:"users" valid:"required"` +// FileDatabaseModel is the model of users file database. +type FileDatabaseModel struct { + Users map[string]FileDatabaseUserDetailsModel `yaml:"users" json:"users" valid:"required" jsonschema:"required,title=Users" jsonschema_description:"The dictionary of users"` } -// ReadToFileUserDatabase reads the DatabaseModel into a YAMLUserDatabase. -func (m *DatabaseModel) ReadToFileUserDatabase(db *YAMLUserDatabase) (err error) { - users := map[string]DatabaseUserDetails{} +// ReadToFileUserDatabase reads the FileDatabaseModel into a FileUserDatabase. +func (m *FileDatabaseModel) ReadToFileUserDatabase(db *FileUserDatabase) (err error) { + users := map[string]FileUserDatabaseUserDetails{} - var udm *DatabaseUserDetails + var udm *FileUserDatabaseUserDetails for user, details := range m.Users { if udm, err = details.ToDatabaseUserDetailsModel(user); err != nil { @@ -262,8 +265,8 @@ func (m *DatabaseModel) ReadToFileUserDatabase(db *YAMLUserDatabase) (err error) return nil } -// Read a DatabaseModel from disk. -func (m *DatabaseModel) Read(filePath string) (err error) { +// Read a FileDatabaseModel from disk. +func (m *FileDatabaseModel) Read(filePath string) (err error) { var ( content []byte ok bool @@ -292,8 +295,8 @@ func (m *DatabaseModel) Read(filePath string) (err error) { return nil } -// Write a DatabaseModel to disk. -func (m *DatabaseModel) Write(fileName string) (err error) { +// Write a FileDatabaseModel to disk. +func (m *FileDatabaseModel) Write(fileName string) (err error) { var ( data []byte ) @@ -305,26 +308,26 @@ func (m *DatabaseModel) Write(fileName string) (err error) { return os.WriteFile(fileName, data, fileAuthenticationMode) } -// UserDetailsModel is the model of user details in the file database. -type UserDetailsModel struct { - HashedPassword string `yaml:"password" valid:"required"` - DisplayName string `yaml:"displayname" valid:"required"` - Email string `yaml:"email"` - Groups []string `yaml:"groups"` - Disabled bool `yaml:"disabled"` +// FileDatabaseUserDetailsModel is the model of user details in the file database. +type FileDatabaseUserDetailsModel struct { + Password string `yaml:"password" valid:"required"` + DisplayName string `yaml:"displayname" valid:"required"` + Email string `yaml:"email"` + Groups []string `yaml:"groups"` + Disabled bool `yaml:"disabled"` } -// ToDatabaseUserDetailsModel converts a UserDetailsModel into a *DatabaseUserDetails. -func (m UserDetailsModel) ToDatabaseUserDetailsModel(username string) (model *DatabaseUserDetails, err error) { +// ToDatabaseUserDetailsModel converts a FileDatabaseUserDetailsModel into a *FileUserDatabaseUserDetails. +func (m FileDatabaseUserDetailsModel) ToDatabaseUserDetailsModel(username string) (model *FileUserDatabaseUserDetails, err error) { var d algorithm.Digest - if d, err = crypt.Decode(m.HashedPassword); err != nil { + if d, err = crypt.Decode(m.Password); err != nil { return nil, err } - return &DatabaseUserDetails{ + return &FileUserDatabaseUserDetails{ Username: username, - Digest: d, + Password: schema.NewPasswordDigest(d), Disabled: m.Disabled, DisplayName: m.DisplayName, Email: m.Email, diff --git a/internal/authentication/file_user_provider_database_mock_test.go b/internal/authentication/file_user_provider_database_mock_test.go index 26e1e3a68..fde875135 100644 --- a/internal/authentication/file_user_provider_database_mock_test.go +++ b/internal/authentication/file_user_provider_database_mock_test.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/authelia/authelia/v4/internal/authentication (interfaces: FileUserDatabase) +// Source: github.com/authelia/authelia/v4/internal/authentication (interfaces: FileUserProviderDatabase) // Package authentication is a generated GoMock package. package authentication @@ -10,7 +10,7 @@ import ( gomock "github.com/golang/mock/gomock" ) -// MockFileUserDatabase is a mock of FileUserDatabase interface. +// MockFileUserDatabase is a mock of FileUserProviderDatabase interface. type MockFileUserDatabase struct { ctrl *gomock.Controller recorder *MockFileUserDatabaseMockRecorder @@ -34,10 +34,10 @@ func (m *MockFileUserDatabase) EXPECT() *MockFileUserDatabaseMockRecorder { } // GetUserDetails mocks base method. -func (m *MockFileUserDatabase) GetUserDetails(arg0 string) (DatabaseUserDetails, error) { +func (m *MockFileUserDatabase) GetUserDetails(arg0 string) (FileUserDatabaseUserDetails, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUserDetails", arg0) - ret0, _ := ret[0].(DatabaseUserDetails) + ret0, _ := ret[0].(FileUserDatabaseUserDetails) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -77,7 +77,7 @@ func (mr *MockFileUserDatabaseMockRecorder) Save() *gomock.Call { } // SetUserDetails mocks base method. -func (m *MockFileUserDatabase) SetUserDetails(arg0 string, arg1 *DatabaseUserDetails) { +func (m *MockFileUserDatabase) SetUserDetails(arg0 string, arg1 *FileUserDatabaseUserDetails) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetUserDetails", arg0, arg1) } diff --git a/internal/authentication/file_user_provider_database_test.go b/internal/authentication/file_user_provider_database_test.go index f8bb21d78..48371f787 100644 --- a/internal/authentication/file_user_provider_database_test.go +++ b/internal/authentication/file_user_provider_database_test.go @@ -10,7 +10,7 @@ import ( ) func TestDatabaseModel_Read(t *testing.T) { - model := &DatabaseModel{} + model := &FileDatabaseModel{} dir := t.TempDir() diff --git a/internal/authentication/file_user_provider_test.go b/internal/authentication/file_user_provider_test.go index e1078acc0..d6bb25730 100644 --- a/internal/authentication/file_user_provider_test.go +++ b/internal/authentication/file_user_provider_test.go @@ -49,7 +49,7 @@ func TestShouldErrorFailCreateDB(t *testing.T) { f := filepath.Join(dir, "x", "users.yml") - provider := NewFileUserProvider(&schema.FileAuthenticationBackend{Path: f, Password: schema.DefaultPasswordConfig}) + provider := NewFileUserProvider(&schema.AuthenticationBackendFile{Path: f, Password: schema.DefaultPasswordConfig}) require.NotNil(t, provider) @@ -70,7 +70,7 @@ func TestShouldErrorBadPasswordConfig(t *testing.T) { require.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600)) - provider := NewFileUserProvider(&schema.FileAuthenticationBackend{Path: f}) + provider := NewFileUserProvider(&schema.AuthenticationBackendFile{Path: f}) require.NotNil(t, provider) @@ -85,7 +85,7 @@ func TestShouldNotPanicOnNilDB(t *testing.T) { assert.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600)) provider := &FileUserProvider{ - config: &schema.FileAuthenticationBackend{Path: f, Password: schema.DefaultPasswordConfig}, + config: &schema.AuthenticationBackendFile{Path: f, Password: schema.DefaultPasswordConfig}, mutex: &sync.Mutex{}, timeoutReload: time.Now().Add(-1 * time.Second), } @@ -130,7 +130,7 @@ func TestShouldReloadDatabase(t *testing.T) { provider.config.Path = p - provider.database = NewYAMLUserDatabase(p, provider.config.Search.Email, provider.config.Search.CaseInsensitive) + provider.database = NewFileUserDatabase(p, provider.config.Search.Email, provider.config.Search.CaseInsensitive) }, false, "", @@ -141,7 +141,7 @@ func TestShouldReloadDatabase(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - provider := NewFileUserProvider(&schema.FileAuthenticationBackend{ + provider := NewFileUserProvider(&schema.AuthenticationBackendFile{ Path: path, Password: schema.DefaultPasswordConfig, }) @@ -307,10 +307,10 @@ func TestShouldUpdatePasswordHashingAlgorithmToArgon2id(t *testing.T) { assert.NoError(t, provider.StartupCheck()) - db, ok := provider.database.(*YAMLUserDatabase) + db, ok := provider.database.(*FileUserDatabase) require.True(t, ok) - assert.True(t, strings.HasPrefix(db.Users["harry"].Digest.Encode(), "$6$")) + assert.True(t, strings.HasPrefix(db.Users["harry"].Password.Encode(), "$6$")) err := provider.UpdatePassword("harry", "newpassword") assert.NoError(t, err) @@ -322,7 +322,7 @@ func TestShouldUpdatePasswordHashingAlgorithmToArgon2id(t *testing.T) { ok, err = provider.CheckUserPassword("harry", "newpassword") assert.NoError(t, err) assert.True(t, ok) - assert.True(t, strings.HasPrefix(db.Users["harry"].Digest.Encode(), "$argon2id$")) + assert.True(t, strings.HasPrefix(db.Users["harry"].Password.Encode(), "$argon2id$")) }) } @@ -337,10 +337,10 @@ func TestShouldUpdatePasswordHashingAlgorithmToSHA512(t *testing.T) { assert.NoError(t, provider.StartupCheck()) - db, ok := provider.database.(*YAMLUserDatabase) + db, ok := provider.database.(*FileUserDatabase) require.True(t, ok) - assert.True(t, strings.HasPrefix(db.Users["john"].Digest.Encode(), "$argon2id$")) + assert.True(t, strings.HasPrefix(db.Users["john"].Password.Encode(), "$argon2id$")) err := provider.UpdatePassword("john", "newpassword") assert.NoError(t, err) @@ -352,7 +352,7 @@ func TestShouldUpdatePasswordHashingAlgorithmToSHA512(t *testing.T) { ok, err = provider.CheckUserPassword("john", "newpassword") assert.NoError(t, err) assert.True(t, ok) - assert.True(t, strings.HasPrefix(db.Users["john"].Digest.Encode(), "$6$")) + assert.True(t, strings.HasPrefix(db.Users["john"].Password.Encode(), "$6$")) }) } @@ -388,7 +388,7 @@ func TestShouldRaiseWhenLoadingDatabaseWithBadSchemaForFirstTime(t *testing.T) { provider := NewFileUserProvider(&config) - assert.EqualError(t, provider.StartupCheck(), "error reading the authentication database: could not validate the schema: Users: non zero value required") + assert.EqualError(t, provider.StartupCheck(), "error reading the authentication database: could not validate the schema: users: non zero value required") }) } @@ -586,15 +586,15 @@ func TestShouldAllowLookupCI(t *testing.T) { func TestNewFileCryptoHashFromConfig(t *testing.T) { testCases := []struct { name string - have schema.Password + have schema.AuthenticationBackendFilePassword expected any err string }{ { "ShouldCreatePBKDF2", - schema.Password{ + schema.AuthenticationBackendFilePassword{ Algorithm: "pbkdf2", - PBKDF2: schema.PBKDF2Password{ + PBKDF2: schema.AuthenticationBackendFilePasswordPBKDF2{ Variant: "sha256", Iterations: 100000, SaltLength: 16, @@ -605,9 +605,9 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) { }, { "ShouldCreateSCrypt", - schema.Password{ + schema.AuthenticationBackendFilePassword{ Algorithm: "scrypt", - SCrypt: schema.SCryptPassword{ + SCrypt: schema.AuthenticationBackendFilePasswordSCrypt{ Iterations: 12, SaltLength: 16, Parallelism: 1, @@ -620,9 +620,9 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) { }, { "ShouldCreateBCrypt", - schema.Password{ + schema.AuthenticationBackendFilePassword{ Algorithm: "bcrypt", - BCrypt: schema.BCryptPassword{ + BCrypt: schema.AuthenticationBackendFilePasswordBCrypt{ Variant: "standard", Cost: 12, }, @@ -632,7 +632,7 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) { }, { "ShouldFailToCreateSCryptInvalidParameter", - schema.Password{ + schema.AuthenticationBackendFilePassword{ Algorithm: "scrypt", }, nil, @@ -640,7 +640,7 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) { }, { "ShouldFailUnknown", - schema.Password{ + schema.AuthenticationBackendFilePassword{ Algorithm: "unknown", }, nil, @@ -688,7 +688,7 @@ func TestHashError(t *testing.T) { func TestDatabaseError(t *testing.T) { WithDatabase(t, UserDatabaseContent, func(path string) { - db := NewYAMLUserDatabase(path, false, false) + db := NewFileUserDatabase(path, false, false) assert.NoError(t, db.Load()) config := DefaultFileAuthenticationBackendConfiguration @@ -717,7 +717,7 @@ func TestDatabaseError(t *testing.T) { } var ( - DefaultFileAuthenticationBackendConfiguration = schema.FileAuthenticationBackend{ + DefaultFileAuthenticationBackendConfiguration = schema.AuthenticationBackendFile{ Path: "", Password: schema.DefaultCIPasswordConfig, } diff --git a/internal/authentication/ldap_user_provider.go b/internal/authentication/ldap_user_provider.go index df8f36da1..d35c72503 100644 --- a/internal/authentication/ldap_user_provider.go +++ b/internal/authentication/ldap_user_provider.go @@ -18,7 +18,7 @@ import ( // LDAPUserProvider is a UserProvider that connects to LDAP servers like ActiveDirectory, OpenLDAP, OpenDJ, FreeIPA, etc. type LDAPUserProvider struct { - config schema.LDAPAuthenticationBackend + config schema.AuthenticationBackendLDAP tlsConfig *tls.Config dialOpts []ldap.DialOpt log *logrus.Logger @@ -57,7 +57,7 @@ func NewLDAPUserProvider(config schema.AuthenticationBackend, certPool *x509.Cer } // NewLDAPUserProviderWithFactory creates a new instance of LDAPUserProvider with the specified LDAPClientFactory. -func NewLDAPUserProviderWithFactory(config schema.LDAPAuthenticationBackend, disableResetPassword bool, certPool *x509.CertPool, factory LDAPClientFactory) (provider *LDAPUserProvider) { +func NewLDAPUserProviderWithFactory(config schema.AuthenticationBackendLDAP, disableResetPassword bool, certPool *x509.CertPool, factory LDAPClientFactory) (provider *LDAPUserProvider) { if config.TLS == nil { config.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS } diff --git a/internal/authentication/ldap_user_provider_test.go b/internal/authentication/ldap_user_provider_test.go index 1664909fa..c0e989429 100644 --- a/internal/authentication/ldap_user_provider_test.go +++ b/internal/authentication/ldap_user_provider_test.go @@ -17,13 +17,13 @@ import ( ) func TestNewLDAPUserProvider(t *testing.T) { - provider := NewLDAPUserProvider(schema.AuthenticationBackend{LDAP: &schema.LDAPAuthenticationBackend{}}, nil) + provider := NewLDAPUserProvider(schema.AuthenticationBackend{LDAP: &schema.AuthenticationBackendLDAP{}}, nil) assert.NotNil(t, provider) } func TestNewLDAPUserProviderWithFactoryWithoutFactory(t *testing.T) { - provider := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackend{}, false, nil, nil) + provider := NewLDAPUserProviderWithFactory(schema.AuthenticationBackendLDAP{}, false, nil, nil) assert.NotNil(t, provider) @@ -38,7 +38,7 @@ func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", @@ -70,7 +70,7 @@ func TestShouldCreateTLSConnectionWhenSchemeIsLDAPS(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPSAddress, User: "cn=admin,dc=example,dc=com", Password: "password", @@ -120,7 +120,7 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) { mockFactory := NewMockLDAPClientFactory(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPSAddress, GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))", }, @@ -150,23 +150,23 @@ func TestResolveGroupsFilter(t *testing.T) { testCases := []struct { name string - have schema.LDAPAuthenticationBackend + have schema.AuthenticationBackendLDAP input string profile ldapUserProfile expected string }{ { "ShouldResolveEmptyFilter", - schema.LDAPAuthenticationBackend{}, + schema.AuthenticationBackendLDAP{}, "", ldapUserProfile{}, "", }, { "ShouldResolveMemberOfRDNFilter", - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ GroupsFilter: "(|{memberof:rdn})", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", GroupName: "cn", MemberOf: "memberOf", @@ -183,9 +183,9 @@ func TestResolveGroupsFilter(t *testing.T) { }, { "ShouldResolveMemberOfDNFilter", - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ GroupsFilter: "(|{memberof:dn})", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", GroupName: "cn", MemberOf: "memberOf", @@ -246,7 +246,7 @@ func (e *ExtendedSearchRequestMatcher) String() string { func TestShouldCheckLDAPEpochFilters(t *testing.T) { type have struct { users string - attr schema.LDAPAuthenticationAttributes + attr schema.AuthenticationBackendLDAPAttributes } type expected struct { @@ -302,7 +302,7 @@ func TestShouldCheckLDAPEpochFilters(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ UsersFilter: tc.have.users, Attributes: tc.have.attr, BaseDN: "dc=example,dc=com", @@ -326,11 +326,11 @@ func TestShouldCheckLDAPServerExtensions(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -394,11 +394,11 @@ func TestShouldNotCheckLDAPServerExtensionsWhenRootDSEReturnsMoreThanOneEntry(t mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -463,11 +463,11 @@ func TestShouldCheckLDAPServerControlTypes(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -531,11 +531,11 @@ func TestShouldNotEnablePasswdModifyExtensionOrControlTypes(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -599,11 +599,11 @@ func TestShouldReturnCheckServerConnectError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -635,11 +635,11 @@ func TestShouldReturnCheckServerSearchError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -683,12 +683,12 @@ func TestShouldPermitRootDSEFailure(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ PermitFeatureDetectionFailure: true, Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -747,11 +747,11 @@ func TestShouldEscapeUserInput(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -784,11 +784,11 @@ func TestShouldReturnEmailWhenAttributeSameAsUsername(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "mail", Mail: "mail", DisplayName: "displayName", @@ -858,11 +858,11 @@ func TestShouldReturnUsernameAndBlankDisplayNameWhenAttributesTheSame(t *testing mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "uid", @@ -932,11 +932,11 @@ func TestShouldReturnBlankEmailAndDisplayNameWhenAttrsLenZero(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1013,12 +1013,12 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", UsersFilter: "(&({username_attribute}={input})(&(objectCategory=person)(objectClass=user)))", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1092,11 +1092,11 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1169,11 +1169,11 @@ func TestLDAPUserProvider_GetDetails_ShouldReturnOnUserError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1217,11 +1217,11 @@ func TestLDAPUserProvider_GetDetails_ShouldReturnOnGroupsError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1290,11 +1290,11 @@ func TestShouldNotCrashWhenEmailsAreNotRetrievedFromLDAP(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", DisplayName: "displayName", MemberOf: "memberOf", @@ -1356,11 +1356,11 @@ func TestShouldUnauthenticatedBind(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", DisplayName: "displayName", MemberOf: "memberOf", @@ -1422,11 +1422,11 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1498,11 +1498,11 @@ func TestShouldReturnUsernameFromLDAPSearchModeMemberOfRDN(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -1588,11 +1588,11 @@ func TestShouldReturnUsernameFromLDAPSearchModeMemberOfDN(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "CN=Administrator,CN=Users,DC=example,DC=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -1676,11 +1676,11 @@ func TestShouldReturnErrSearchMemberOf(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "CN=Administrator,CN=Users,DC=example,DC=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -1760,11 +1760,11 @@ func TestShouldReturnErrUnknownSearchMode(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "CN=Administrator,CN=Users,DC=example,DC=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -1836,11 +1836,11 @@ func TestShouldSkipEmptyAttributesSearchModeMemberOf(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "CN=Administrator,CN=Users,DC=example,DC=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -1950,11 +1950,11 @@ func TestShouldSkipEmptyAttributesSearchModeFilter(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "CN=Administrator,CN=Users,DC=example,DC=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -2064,11 +2064,11 @@ func TestShouldSkipEmptyGroupsResultMemberOf(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2146,11 +2146,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndResult(t *testing.T) mockClientReferralAlt := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2275,11 +2275,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndNoResult(t *testing. mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2366,11 +2366,11 @@ func TestShouldReturnDialErrDuringReferralSearchUsernameFromLDAPWithReferralsInE mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2421,11 +2421,11 @@ func TestShouldReturnSearchErrDuringReferralSearchUsernameFromLDAPWithReferralsI mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2485,11 +2485,11 @@ func TestShouldNotReturnUsernameFromLDAPWithReferralsInErrorAndReferralsNotPermi mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2535,11 +2535,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsErr(t *testing.T) { mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2626,11 +2626,11 @@ func TestShouldNotUpdateUserPasswordConnect(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2696,11 +2696,11 @@ func TestShouldNotUpdateUserPasswordGetDetails(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2776,11 +2776,11 @@ func TestShouldUpdateUserPassword(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2886,12 +2886,12 @@ func TestShouldUpdateUserPasswordMSAD(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -2999,12 +2999,12 @@ func TestShouldUpdateUserPasswordMSADWithReferrals(t *testing.T) { mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3130,12 +3130,12 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralConnectErr(t *test mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3252,12 +3252,12 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralModifyErr(t *testi mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3387,12 +3387,12 @@ func TestShouldUpdateUserPasswordMSADWithoutReferrals(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3504,11 +3504,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtension(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3614,11 +3614,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferrals(t *testing.T mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3744,11 +3744,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithoutReferrals(t *testin mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3860,11 +3860,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralConne mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -3981,11 +3981,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralPassw mockClientReferral := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4115,12 +4115,12 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHints(t *testing mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -4230,12 +4230,12 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHintsDeprecated( mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -4345,12 +4345,12 @@ func TestShouldUpdateUserPasswordActiveDirectory(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "activedirectory", Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ DistinguishedName: "distinguishedName", Username: "sAMAccountName", Mail: "mail", @@ -4460,12 +4460,12 @@ func TestShouldUpdateUserPasswordBasic(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Implementation: "custom", Address: testLDAPAddress, User: "uid=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4571,11 +4571,11 @@ func TestShouldReturnErrorWhenMultipleUsernameAttributes(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4640,11 +4640,11 @@ func TestShouldReturnErrorWhenZeroUsernameAttributes(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4709,11 +4709,11 @@ func TestShouldReturnErrorWhenUsernameAttributeNotReturned(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4774,11 +4774,11 @@ func TestShouldReturnErrorWhenMultipleUsersFound(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4860,11 +4860,11 @@ func TestShouldReturnErrorWhenNoDN(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -4929,11 +4929,11 @@ func TestShouldCheckValidUserPassword(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5000,11 +5000,11 @@ func TestShouldNotCheckValidUserPasswordWithConnectError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5042,11 +5042,11 @@ func TestShouldNotCheckValidUserPasswordWithGetProfileError(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5087,11 +5087,11 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5158,11 +5158,11 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5237,11 +5237,11 @@ func TestShouldParseDynamicConfiguration(t *testing.T) { mockFactory := NewMockLDAPClientFactory(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5289,11 +5289,11 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5304,7 +5304,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T AdditionalUsersDN: "ou=users", BaseDN: "dc=example,dc=com", StartTLS: true, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ SkipVerify: true, }, }, @@ -5380,11 +5380,11 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) { mockClient := NewMockLDAPClient(ctrl) provider := NewLDAPUserProviderWithFactory( - schema.LDAPAuthenticationBackend{ + schema.AuthenticationBackendLDAP{ Address: testLDAPSAddress, User: "cn=admin,dc=example,dc=com", Password: "password", - Attributes: schema.LDAPAuthenticationAttributes{ + Attributes: schema.AuthenticationBackendLDAPAttributes{ Username: "uid", Mail: "mail", DisplayName: "displayName", @@ -5394,7 +5394,7 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) { AdditionalUsersDN: "ou=users", BaseDN: "dc=example,dc=com", StartTLS: true, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ SkipVerify: true, }, }, diff --git a/internal/authorization/access_control_query.go b/internal/authorization/access_control_query.go index e83b08736..36b67d050 100644 --- a/internal/authorization/access_control_query.go +++ b/internal/authorization/access_control_query.go @@ -8,7 +8,7 @@ import ( ) // NewAccessControlQuery creates a new AccessControlQuery rule type. -func NewAccessControlQuery(config [][]schema.ACLQueryRule) (rules []AccessControlQuery) { +func NewAccessControlQuery(config [][]schema.AccessControlRuleQuery) (rules []AccessControlQuery) { if len(config) == 0 { return nil } @@ -47,8 +47,8 @@ func (acq AccessControlQuery) IsMatch(object Object) (isMatch bool) { return true } -// NewAccessControlQueryObjectMatcher creates a new ObjectMatcher rule type from a schema.ACLQueryRule. -func NewAccessControlQueryObjectMatcher(rule schema.ACLQueryRule) (matcher ObjectMatcher, err error) { +// NewAccessControlQueryObjectMatcher creates a new ObjectMatcher rule type from a schema.AccessControlRuleQuery. +func NewAccessControlQueryObjectMatcher(rule schema.AccessControlRuleQuery) (matcher ObjectMatcher, err error) { switch rule.Operator { case operatorPresent, operatorAbsent: return &AccessControlQueryMatcherPresent{key: rule.Key, present: rule.Operator == operatorPresent}, nil diff --git a/internal/authorization/access_control_query_test.go b/internal/authorization/access_control_query_test.go index 12f40620f..6905787d1 100644 --- a/internal/authorization/access_control_query_test.go +++ b/internal/authorization/access_control_query_test.go @@ -11,13 +11,13 @@ import ( func TestNewAccessControlQuery(t *testing.T) { testCases := []struct { name string - have [][]schema.ACLQueryRule + have [][]schema.AccessControlRuleQuery expected []AccessControlQuery matches [][]Object }{ { "ShouldSkipInvalidTypeEqual", - [][]schema.ACLQueryRule{ + [][]schema.AccessControlRuleQuery{ { {Operator: operatorEqual, Key: "example", Value: 1}, }, @@ -27,7 +27,7 @@ func TestNewAccessControlQuery(t *testing.T) { }, { "ShouldSkipInvalidTypePattern", - [][]schema.ACLQueryRule{ + [][]schema.AccessControlRuleQuery{ { {Operator: operatorPattern, Key: "example", Value: 1}, }, @@ -37,7 +37,7 @@ func TestNewAccessControlQuery(t *testing.T) { }, { "ShouldSkipInvalidOperator", - [][]schema.ACLQueryRule{ + [][]schema.AccessControlRuleQuery{ { {Operator: "nop", Key: "example", Value: 1}, }, diff --git a/internal/authorization/access_control_rule.go b/internal/authorization/access_control_rule.go index 968d4ce28..fa2953ca6 100644 --- a/internal/authorization/access_control_rule.go +++ b/internal/authorization/access_control_rule.go @@ -7,8 +7,8 @@ import ( "github.com/authelia/authelia/v4/internal/utils" ) -// NewAccessControlRules converts a schema.AccessControlConfiguration into an AccessControlRule slice. -func NewAccessControlRules(config schema.AccessControlConfiguration) (rules []*AccessControlRule) { +// NewAccessControlRules converts a schema.AccessControl into an AccessControlRule slice. +func NewAccessControlRules(config schema.AccessControl) (rules []*AccessControlRule) { networksMap, networksCacheMap := parseSchemaNetworks(config.Networks) for i, schemaRule := range config.Rules { @@ -19,7 +19,7 @@ func NewAccessControlRules(config schema.AccessControlConfiguration) (rules []*A } // NewAccessControlRule parses a schema ACL and generates an internal ACL. -func NewAccessControlRule(pos int, rule schema.ACLRule, networksMap map[string][]*net.IPNet, networksCacheMap map[string]*net.IPNet) *AccessControlRule { +func NewAccessControlRule(pos int, rule schema.AccessControlRule, networksMap map[string][]*net.IPNet, networksCacheMap map[string]*net.IPNet) *AccessControlRule { r := &AccessControlRule{ Position: pos, Query: NewAccessControlQuery(rule.Query), diff --git a/internal/authorization/authorizer_test.go b/internal/authorization/authorizer_test.go index fab59496f..a0b5982e0 100644 --- a/internal/authorization/authorizer_test.go +++ b/internal/authorization/authorizer_test.go @@ -22,7 +22,7 @@ type AuthorizerTester struct { *Authorizer } -func NewAuthorizerTester(config schema.AccessControlConfiguration) *AuthorizerTester { +func NewAuthorizerTester(config schema.AccessControl) *AuthorizerTester { fullConfig := &schema.Configuration{ AccessControl: config, } @@ -51,7 +51,7 @@ func (s *AuthorizerTester) GetRuleMatchResults(subject Subject, requestURI, meth } type AuthorizerTesterBuilder struct { - config schema.AccessControlConfiguration + config schema.AccessControl } func NewAuthorizerBuilder() *AuthorizerTesterBuilder { @@ -63,7 +63,7 @@ func (b *AuthorizerTesterBuilder) WithDefaultPolicy(policy string) *AuthorizerTe return b } -func (b *AuthorizerTesterBuilder) WithRule(rule schema.ACLRule) *AuthorizerTesterBuilder { +func (b *AuthorizerTesterBuilder) WithRule(rule schema.AccessControlRule) *AuthorizerTesterBuilder { b.config.Rules = append(b.config.Rules, rule) return b } @@ -133,7 +133,7 @@ func (s *AuthorizerSuite) TestShouldCheckDefaultDeniedConfig() { func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"*.example.com"}, Policy: bypass, }). @@ -150,11 +150,11 @@ func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() { func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"{user}.example.com"}, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"{group}.example.com"}, Policy: oneFactor, }). @@ -169,7 +169,7 @@ func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() { func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"*.example.com", "other.com"}, Policy: bypass, }). @@ -189,15 +189,15 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() { func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"single.example.com"}, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public.example.com"}, Policy: bypass, }). @@ -212,9 +212,9 @@ func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() { func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"one.example.com"}, - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { { Operator: operatorEqual, @@ -235,9 +235,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { }, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"two.example.com"}, - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { { Operator: operatorEqual, @@ -255,9 +255,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { }, Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"three.example.com"}, - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { { Operator: operatorNotEqual, @@ -273,9 +273,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { }, Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"four.example.com"}, - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { { Operator: operatorPattern, @@ -286,9 +286,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { }, Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"five.example.com"}, - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { { Operator: operatorNotPattern, @@ -335,16 +335,16 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: bypass, Subjects: [][]string{{"user:john"}}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"*.example.com"}, Policy: twoFactor, }). @@ -357,24 +357,24 @@ func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() { func (s *AuthorizerSuite) TestShouldCheckDomainMatching() { tester := NewAuthorizerBuilder(). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public.example.com"}, Policy: bypass, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"one-factor.example.com"}, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"two-factor.example.com"}, Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"*.example.com"}, Policy: oneFactor, Subjects: [][]string{{"group:admins"}}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"*.example.com"}, Policy: twoFactor, }). @@ -466,23 +466,23 @@ func (s *AuthorizerSuite) TestShouldCheckDomainRegexMatching() { } tester := NewAuthorizerBuilder(). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example.com$`}), Policy: bypass, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example2.com$`}), Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ DomainsRegex: createSliceRegexRule(s.T(), []string{`^(?P[a-zA-Z0-9]+)\.regex.com$`}), Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ DomainsRegex: createSliceRegexRule(s.T(), []string{`^group-(?P[a-zA-Z0-9]+)\.regex.com$`}), Policy: twoFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.(one|two).com$`}), Policy: twoFactor, }). @@ -548,17 +548,17 @@ func (s *AuthorizerSuite) TestShouldCheckResourceSubjectMatching() { } tester := NewAuthorizerBuilder(). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"id.example.com"}, Policy: oneFactor, Resources: createSliceRegexRule(s.T(), []string{`^/(?P[a-zA-Z0-9]+)/personal(/|/.*)?$`, `^/(?P[a-zA-Z0-9]+)/group(/|/.*)?$`}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"id.example.com"}, Policy: deny, Resources: createSliceRegexRule(s.T(), []string{`^/([a-zA-Z0-9]+)/personal(/|/.*)?$`, `^/([a-zA-Z0-9]+)/group(/|/.*)?$`}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"id.example.com"}, Policy: bypass, }). @@ -629,7 +629,7 @@ func (s *AuthorizerSuite) TestShouldCheckResourceSubjectMatching() { func (s *AuthorizerSuite) TestShouldCheckUserMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Subjects: [][]string{{"user:john"}}, @@ -643,7 +643,7 @@ func (s *AuthorizerSuite) TestShouldCheckUserMatching() { func (s *AuthorizerSuite) TestShouldCheckGroupMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Subjects: [][]string{{"group:admins"}}, @@ -657,7 +657,7 @@ func (s *AuthorizerSuite) TestShouldCheckGroupMatching() { func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Subjects: [][]string{{"group:admins"}, {"user:bob"}}, @@ -673,7 +673,7 @@ func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Subjects: [][]string{{"group:admins", "user:bob"}, {"group:admins", "group:dev"}}, @@ -688,27 +688,27 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckIPMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: bypass, Networks: []string{"192.168.1.8", "10.0.0.8"}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Networks: []string{"10.0.0.7"}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"net.example.com"}, Policy: twoFactor, Networks: []string{"10.0.0.0/8"}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"ipv6.example.com"}, Policy: twoFactor, Networks: []string{"fec0::1/64"}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"ipv6-alt.example.com"}, Policy: twoFactor, Networks: []string{"fec0::1"}, @@ -732,17 +732,17 @@ func (s *AuthorizerSuite) TestShouldCheckIPMatching() { func (s *AuthorizerSuite) TestShouldCheckMethodMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: bypass, Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: oneFactor, Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch, fasthttp.MethodPost}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"protected.example.com"}, Policy: twoFactor, Methods: []string{fasthttp.MethodDelete}, @@ -773,27 +773,27 @@ func (s *AuthorizerSuite) TestShouldCheckResourceMatching() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"resource.example.com"}, Policy: bypass, Resources: createSliceRegexRule(s.T(), []string{"^/case/[a-z]+$", "^/$"}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"resource.example.com"}, Policy: bypass, Resources: createSliceRegexRule(s.T(), []string{"^/bypass/.*$", "^/$", "embedded"}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"resource.example.com"}, Policy: oneFactor, Resources: createSliceRegexRule(s.T(), []string{"^/one_factor/.*$"}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"resource.example.com"}, Policy: twoFactor, Resources: createSliceRegexRule(s.T(), []string{"^/a/longer/rule/.*$"}), }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"resource.example.com"}, Policy: twoFactor, Resources: createSliceRegexRule(s.T(), []string{"^/an/exact/path/$"}), @@ -833,15 +833,15 @@ func (s *AuthorizerSuite) TestShouldCheckResourceMatching() { // This test assures that rules without domains (not allowed by schema validator at this time) will pass validation correctly. func (s *AuthorizerSuite) TestShouldMatchAnyDomainIfBlank() { tester := NewAuthorizerBuilder(). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Policy: bypass, Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Policy: oneFactor, Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch}, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Policy: twoFactor, Methods: []string{fasthttp.MethodDelete}, }). @@ -875,37 +875,37 @@ func (s *AuthorizerSuite) TestShouldMatchResourceWithSubjectRules() { tester := NewAuthorizerBuilder(). WithDefaultPolicy(deny). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public.example.com"}, Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Subjects: [][]string{{"group:admins"}}, Policy: oneFactor, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public.example.com"}, Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Policy: deny, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public.example.com"}, Policy: bypass, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public2.example.com"}, Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Subjects: [][]string{{"group:admins"}}, Policy: bypass, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public2.example.com"}, Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Policy: deny, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"public2.example.com"}, Policy: bypass, }). - WithRule(schema.ACLRule{ + WithRule(schema.AccessControlRule{ Domains: []string{"private.example.com"}, Subjects: [][]string{{"group:admins"}}, Policy: twoFactor, @@ -1004,9 +1004,9 @@ func TestRunSuite(t *testing.T) { func TestNewAuthorizer(t *testing.T) { config := &schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: deny, - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: twoFactor, @@ -1039,9 +1039,9 @@ func TestNewAuthorizer(t *testing.T) { func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) { config := &schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: deny, - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: oneFactor, @@ -1060,9 +1060,9 @@ func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) { func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) { config := &schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: deny, - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: oneFactor, @@ -1070,8 +1070,8 @@ func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) { }, }, IdentityProviders: schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ - Clients: []schema.OpenIDConnectClient{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { Policy: oneFactor, }, diff --git a/internal/authorization/util.go b/internal/authorization/util.go index 0e8c89d9b..4876841d8 100644 --- a/internal/authorization/util.go +++ b/internal/authorization/util.go @@ -138,7 +138,7 @@ func schemaNetworksToACL(networkRules []string, networksMap map[string][]*net.IP return networks } -func parseSchemaNetworks(schemaNetworks []schema.ACLNetwork) (networksMap map[string][]*net.IPNet, networksCacheMap map[string]*net.IPNet) { +func parseSchemaNetworks(schemaNetworks []schema.AccessControlNetwork) (networksMap map[string][]*net.IPNet, networksCacheMap map[string]*net.IPNet) { // These maps store pointers to the net.IPNet values so we can reuse them efficiently. // The networksMap contains the named networks as keys, the networksCacheMap contains the CIDR notations as keys. networksMap = map[string][]*net.IPNet{} diff --git a/internal/authorization/util_test.go b/internal/authorization/util_test.go index 4313d0ba6..eed420e24 100644 --- a/internal/authorization/util_test.go +++ b/internal/authorization/util_test.go @@ -60,7 +60,7 @@ func TestShouldSplitDomainCorrectly(t *testing.T) { } func TestShouldParseRuleNetworks(t *testing.T) { - schemaNetworks := []schema.ACLNetwork{ + schemaNetworks := []schema.AccessControlNetwork{ { Name: "desktop", Networks: []string{ @@ -105,7 +105,7 @@ func TestShouldParseRuleNetworks(t *testing.T) { } func TestShouldParseACLNetworks(t *testing.T) { - schemaNetworks := []schema.ACLNetwork{ + schemaNetworks := []schema.AccessControlNetwork{ { Name: "test", Networks: []string{ diff --git a/internal/configuration/decode_hooks.go b/internal/configuration/decode_hooks.go index b07be7412..05dbba95f 100644 --- a/internal/configuration/decode_hooks.go +++ b/internal/configuration/decode_hooks.go @@ -490,7 +490,7 @@ func StringToCryptoPrivateKeyHookFunc() mapstructure.DecodeHookFuncType { return data, nil } - field, _ := reflect.TypeOf(schema.TLSConfig{}).FieldByName("PrivateKey") + field, _ := reflect.TypeOf(schema.TLS{}).FieldByName("PrivateKey") expectedType := field.Type if t != expectedType { diff --git a/internal/configuration/schema/access_control.go b/internal/configuration/schema/access_control.go index 79e1c93fa..c621fee51 100644 --- a/internal/configuration/schema/access_control.go +++ b/internal/configuration/schema/access_control.go @@ -1,43 +1,44 @@ package schema -import ( - "regexp" -) +// AccessControl represents the configuration related to ACLs. +type AccessControl struct { + // The default policy if no other policy matches the request. + DefaultPolicy string `koanf:"default_policy" json:"default_policy" jsonschema:"default=deny,enum=deny,enum=one_factor,enum=two_factor,title=Default Authorization Policy" jsonschema_description:"The default policy applied to all authorization requests. Not relevant to OpenID Connect."` -// AccessControlConfiguration represents the configuration related to ACLs. -type AccessControlConfiguration struct { - DefaultPolicy string `koanf:"default_policy"` - Networks []ACLNetwork `koanf:"networks"` - Rules []ACLRule `koanf:"rules"` + // Represents a list of named network groups. + Networks []AccessControlNetwork `koanf:"networks" json:"networks" jsonschema:"title=Named Networks" jsonschema_description:"The list of named networks which can be reused in any ACL rule"` + + // The ACL rules list. + Rules []AccessControlRule `koanf:"rules" json:"rules" jsonschema:"title=Rules List" jsonschema_description:"The list of ACL rules to enumerate for requests"` } -// ACLNetwork represents one ACL network group entry. -type ACLNetwork struct { - Name string `koanf:"name"` - Networks []string `koanf:"networks"` +// AccessControlNetwork represents one ACL network group entry. +type AccessControlNetwork struct { + Name string `koanf:"name" json:"name" jsonschema:"required,title=Network Name" jsonschema_description:"The name of this network to be used in the networks section of the rules section"` + Networks AccessControlNetworkNetworks `koanf:"networks" json:"networks" jsonschema:"required,title=Networks" jsonschema_description:"The remote IP's or network ranges in CIDR notation that this rule applies to"` } -// ACLRule represents one ACL rule entry. -type ACLRule struct { - Domains []string `koanf:"domain"` - DomainsRegex []regexp.Regexp `koanf:"domain_regex"` - Policy string `koanf:"policy"` - Subjects [][]string `koanf:"subject"` - Networks []string `koanf:"networks"` - Resources []regexp.Regexp `koanf:"resources"` - Methods []string `koanf:"methods"` - Query [][]ACLQueryRule `koanf:"query"` +// AccessControlRule represents one ACL rule entry. +type AccessControlRule struct { + Domains AccessControlRuleDomains `koanf:"domain" json:"domain" jsonschema:"oneof_required=Domain,uniqueItems,title=Domain Literals" jsonschema_description:"The literal domains to match the domain against that this rule applies to"` + DomainsRegex AccessControlRuleRegex `koanf:"domain_regex" json:"domain_regex" jsonschema:"oneof_required=Domain Regex,title=Domain Regex Patterns" jsonschema_description:"The regex patterns to match the domain against that this rule applies to"` + Policy string `koanf:"policy" json:"policy" jsonschema:"required,enum=bypass,enum=deny,enum=one_factor,enum=two_factor,title=Rule Policy" jsonschema_description:"The policy this rule applies when all criteria match"` + Subjects AccessControlRuleSubjects `koanf:"subject" json:"subject" jsonschema:"title=AccessControlRuleSubjects" jsonschema_description:"The users or groups that this rule applies to"` + Networks AccessControlRuleNetworks `koanf:"networks" json:"networks" jsonschema:"title=Networks" jsonschema_description:"The remote IP's, network ranges in CIDR notation, or network names that this rule applies to"` + Resources AccessControlRuleRegex `koanf:"resources" json:"resources" jsonschema:"title=Resources or Paths" jsonschema_description:"The regex patterns to match the resource paths that this rule applies to"` + Methods AccessControlRuleMethods `koanf:"methods" json:"methods" jsonschema:"enum=GET,enum=HEAD,enum=POST,enum=PUT,enum=DELETE,enum=CONNECT,enum=OPTIONS,enum=TRACE,enum=PATCH,enum=PROPFIND,enum=PROPPATCH,enum=MKCOL,enum=COPY,enum=MOVE,enum=LOCK,enum=UNLOCK" jsonschema_description:"The list of request methods this rule applies to"` + Query [][]AccessControlRuleQuery `koanf:"query" json:"query" jsonschema:"title=Query Rules" jsonschema_description:"The list of query parameter rules this rule applies to"` } -// ACLQueryRule represents the ACL query criteria. -type ACLQueryRule struct { - Operator string `koanf:"operator"` - Key string `koanf:"key"` - Value any `koanf:"value"` +// AccessControlRuleQuery represents the ACL query criteria. +type AccessControlRuleQuery struct { + Operator string `koanf:"operator" json:"operator" jsonschema:"enum=equal,enum=not equal,enum=present,enum=absent,enum=pattern,enum=not pattern,title=Operator" jsonschema_description:"The list of query parameter rules this rule applies to"` + Key string `koanf:"key" json:"key" jsonschema:"required,title=Key" jsonschema_description:"The Query Parameter key this rule applies to"` + Value any `koanf:"value" json:"value" jsonschema:"title=Value" jsonschema_description:"The Query Parameter value for this rule"` } // DefaultACLNetwork represents the default configuration related to access control network group configuration. -var DefaultACLNetwork = []ACLNetwork{ +var DefaultACLNetwork = []AccessControlNetwork{ { Name: "localhost", Networks: []string{"127.0.0.1"}, @@ -49,7 +50,7 @@ var DefaultACLNetwork = []ACLNetwork{ } // DefaultACLRule represents the default configuration related to access control rule configuration. -var DefaultACLRule = []ACLRule{ +var DefaultACLRule = []AccessControlRule{ { Domains: []string{"public.example.com"}, Policy: "bypass", diff --git a/internal/configuration/schema/authentication.go b/internal/configuration/schema/authentication.go index 19b73b2e9..9aeaa1081 100644 --- a/internal/configuration/schema/authentication.go +++ b/internal/configuration/schema/authentication.go @@ -8,132 +8,143 @@ import ( // AuthenticationBackend represents the configuration related to the authentication backend. type AuthenticationBackend struct { - PasswordReset PasswordResetAuthenticationBackend `koanf:"password_reset"` + PasswordReset AuthenticationBackendPasswordReset `koanf:"password_reset" json:"password_reset" jsonschema:"title=Password Reset" jsonschema_description:"Allows configuration of the password reset behaviour"` - RefreshInterval string `koanf:"refresh_interval"` + RefreshInterval string `koanf:"refresh_interval" json:"refresh_interval" jsonschema:"title=Refresh Interval" jsonschema_description:"How frequently the user details are refreshed from the backend"` - File *FileAuthenticationBackend `koanf:"file"` - LDAP *LDAPAuthenticationBackend `koanf:"ldap"` + // The file authentication backend configuration. + File *AuthenticationBackendFile `koanf:"file" json:"file" jsonschema:"title=File Backend" jsonschema_description:"The file authentication backend configuration"` + LDAP *AuthenticationBackendLDAP `koanf:"ldap" json:"ldap" jsonschema:"title=LDAP Backend" jsonschema_description:"The LDAP authentication backend configuration"` } -// PasswordResetAuthenticationBackend represents the configuration related to password reset functionality. -type PasswordResetAuthenticationBackend struct { - Disable bool `koanf:"disable"` - CustomURL url.URL `koanf:"custom_url"` +// AuthenticationBackendPasswordReset represents the configuration related to password reset functionality. +type AuthenticationBackendPasswordReset struct { + Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the Password Reset option"` + CustomURL url.URL `koanf:"custom_url" json:"custom_url" jsonschema:"Custom URL" jsonschema_description:"Disables the internal Password Reset option and instead redirects users to this specified URL"` } -// FileAuthenticationBackend represents the configuration related to file-based backend. -type FileAuthenticationBackend struct { - Path string `koanf:"path"` - Watch bool `koanf:"watch"` - Password Password `koanf:"password"` +// AuthenticationBackendFile represents the configuration related to file-based backend. +type AuthenticationBackendFile struct { + Path string `koanf:"path" json:"path" jsonschema:"title=Path" jsonschema_description:"The file path to the user database"` + Watch bool `koanf:"watch" json:"watch" jsonschema:"default=false,title=Watch" jsonschema_description:"Enables watching the file for external changes and dynamically reloading the database"` - Search FileSearchAuthenticationBackend `koanf:"search"` + Password AuthenticationBackendFilePassword `koanf:"password" json:"password" jsonschema:"title=Password Options" jsonschema_description:"Allows configuration of the password hashing options when the user passwords are changed directly by Authelia"` + + Search AuthenticationBackendFileSearch `koanf:"search" json:"search" jsonschema:"title=Search" jsonschema_description:"Configures the user searching behaviour"` } -// FileSearchAuthenticationBackend represents the configuration related to file-based backend searching. -type FileSearchAuthenticationBackend struct { - Email bool `koanf:"email"` - CaseInsensitive bool `koanf:"case_insensitive"` +// AuthenticationBackendFileSearch represents the configuration related to file-based backend searching. +type AuthenticationBackendFileSearch struct { + Email bool `koanf:"email" json:"email" jsonschema:"default=false,title=Email Searching" jsonschema_description:"Allows users to either use their username or their configured email as a username"` + CaseInsensitive bool `koanf:"case_insensitive" json:"case_insensitive" jsonschema:"default=false,title=Case Insensitive Searching" jsonschema_description:"Allows usernames to be any case during the search"` } -// Password represents the configuration related to password hashing. -type Password struct { - Algorithm string `koanf:"algorithm"` +// AuthenticationBackendFilePassword represents the configuration related to password hashing. +type AuthenticationBackendFilePassword struct { + Algorithm string `koanf:"algorithm" json:"algorithm" jsonschema:"default=argon2,enum=argon2,enum=sha2crypt,enum=pbkdf2,enum=bcrypt,enum=scrypt,title=Algorithm" jsonschema_description:"The password hashing algorithm to use"` - Argon2 Argon2Password `koanf:"argon2"` - SHA2Crypt SHA2CryptPassword `koanf:"sha2crypt"` - PBKDF2 PBKDF2Password `koanf:"pbkdf2"` - BCrypt BCryptPassword `koanf:"bcrypt"` - SCrypt SCryptPassword `koanf:"scrypt"` + Argon2 AuthenticationBackendFilePasswordArgon2 `koanf:"argon2" json:"argon2" jsonschema:"title=Argon2" jsonschema_description:"Configure the Argon2 password hashing parameters"` + SHA2Crypt AuthenticationBackendFilePasswordSHA2Crypt `koanf:"sha2crypt" json:"sha2crypt" jsonschema:"title=SHA2Crypt" jsonschema_description:"Configure the SHA2Crypt password hashing parameters"` + PBKDF2 AuthenticationBackendFilePasswordPBKDF2 `koanf:"pbkdf2" json:"pbkdf2" jsonschema:"title=PBKDF2" jsonschema_description:"Configure the PBKDF2 password hashing parameters"` + BCrypt AuthenticationBackendFilePasswordBCrypt `koanf:"bcrypt" json:"bcrypt" jsonschema:"title=BCrypt" jsonschema_description:"Configure the BCrypt password hashing parameters"` + SCrypt AuthenticationBackendFilePasswordSCrypt `koanf:"scrypt" json:"scrypt" jsonschema:"title=SCrypt" jsonschema_description:"Configure the SCrypt password hashing parameters"` - Iterations int `koanf:"iterations"` - Memory int `koanf:"memory"` - Parallelism int `koanf:"parallelism"` - KeyLength int `koanf:"key_length"` - SaltLength int `koanf:"salt_length"` + // Deprecated: Use individual password options instead. + Iterations int `koanf:"iterations" json:"iterations" jsonschema:"deprecated"` + + // Deprecated: Use individual password options instead. + Memory int `koanf:"memory" json:"memory" jsonschema:"deprecated"` + + // Deprecated: Use individual password options instead. + Parallelism int `koanf:"parallelism" json:"parallelism" jsonschema:"deprecated"` + + // Deprecated: Use individual password options instead. + KeyLength int `koanf:"key_length" json:"key_length" jsonschema:"deprecated"` + + // Deprecated: Use individual password options instead. + SaltLength int `koanf:"salt_length" json:"salt_length" jsonschema:"deprecated"` } -// Argon2Password represents the argon2 hashing settings. -type Argon2Password struct { - Variant string `koanf:"variant"` - Iterations int `koanf:"iterations"` - Memory int `koanf:"memory"` - Parallelism int `koanf:"parallelism"` - KeyLength int `koanf:"key_length"` - SaltLength int `koanf:"salt_length"` +// AuthenticationBackendFilePasswordArgon2 represents the argon2 hashing settings. +type AuthenticationBackendFilePasswordArgon2 struct { + Variant string `koanf:"variant" json:"variant" jsonschema:"default=argon2id,enum=argon2id,enum=argon2i,enum=argon2d,title=Variant" jsonschema_description:"The Argon2 variant to be used"` + Iterations int `koanf:"iterations" json:"iterations" jsonschema:"default=3,title=Iterations" jsonschema_description:"The number of Argon2 iterations (parameter t) to be used"` + Memory int `koanf:"memory" json:"memory" jsonschema:"default=65536,minimum=8,maximum=4294967295,title=Memory" jsonschema_description:"The Argon2 amount of memory in kibibytes (parameter m) to be used"` + Parallelism int `koanf:"parallelism" json:"parallelism" jsonschema:"default=4,minimum=1,maximum=16777215,title=Parallelism" jsonschema_description:"The Argon2 degree of parallelism (parameter p) to be used"` + KeyLength int `koanf:"key_length" json:"key_length" jsonschema:"default=32,minimum=4,maximum=2147483647,title=Key Length" jsonschema_description:"The Argon2 key output length"` + SaltLength int `koanf:"salt_length" json:"salt_length" jsonschema:"default=16,minimum=1,maximum=2147483647,title=Salt Length" jsonschema_description:"The Argon2 salt length"` } -// SHA2CryptPassword represents the sha2crypt hashing settings. -type SHA2CryptPassword struct { - Variant string `koanf:"variant"` - Iterations int `koanf:"iterations"` - SaltLength int `koanf:"salt_length"` +// AuthenticationBackendFilePasswordSHA2Crypt represents the sha2crypt hashing settings. +type AuthenticationBackendFilePasswordSHA2Crypt struct { + Variant string `koanf:"variant" json:"variant" jsonschema:"default=sha512,enum=sha256,enum=sha512,title=Variant" jsonschema_description:"The SHA2Crypt variant to be used"` + Iterations int `koanf:"iterations" json:"iterations" jsonschema:"default=50000,minimum=1000,maximum=999999999,title=Iterations" jsonschema_description:"The SHA2Crypt iterations (parameter rounds) to be used"` + SaltLength int `koanf:"salt_length" json:"salt_length" jsonschema:"default=16,minimum=1,maximum=16,title=Salt Length" jsonschema_description:"The SHA2Crypt salt length to be used"` } -// PBKDF2Password represents the PBKDF2 hashing settings. -type PBKDF2Password struct { - Variant string `koanf:"variant"` - Iterations int `koanf:"iterations"` - SaltLength int `koanf:"salt_length"` +// AuthenticationBackendFilePasswordPBKDF2 represents the PBKDF2 hashing settings. +type AuthenticationBackendFilePasswordPBKDF2 struct { + Variant string `koanf:"variant" json:"variant" jsonschema:"default=sha512,enum=sha1,enum=sha224,enum=sha256,enum=sha384,enum=sha512,title=Variant" jsonschema_description:"The PBKDF2 variant to be used"` + Iterations int `koanf:"iterations" json:"iterations" jsonschema:"default=310000,minimum=100000,maximum=2147483647,title=Iterations" jsonschema_description:"The PBKDF2 iterations to be used"` + SaltLength int `koanf:"salt_length" json:"salt_length" jsonschema:"default=16,minimum=8,maximum=2147483647,title=Salt Length" jsonschema_description:"The PBKDF2 salt length to be used"` } -// BCryptPassword represents the bcrypt hashing settings. -type BCryptPassword struct { - Variant string `koanf:"variant"` - Cost int `koanf:"cost"` +// AuthenticationBackendFilePasswordBCrypt represents the bcrypt hashing settings. +type AuthenticationBackendFilePasswordBCrypt struct { + Variant string `koanf:"variant" json:"variant" jsonschema:"default=standard,enum=standard,enum=sha256,title=Variant" jsonschema_description:"The BCrypt variant to be used"` + Cost int `koanf:"cost" json:"cost" jsonschema:"default=12,minimum=10,maximum=31,title=Cost" jsonschema_description:"The BCrypt cost to be used"` } -// SCryptPassword represents the scrypt hashing settings. -type SCryptPassword struct { - Iterations int `koanf:"iterations"` - BlockSize int `koanf:"block_size"` - Parallelism int `koanf:"parallelism"` - KeyLength int `koanf:"key_length"` - SaltLength int `koanf:"salt_length"` +// AuthenticationBackendFilePasswordSCrypt represents the scrypt hashing settings. +type AuthenticationBackendFilePasswordSCrypt struct { + Iterations int `koanf:"iterations" json:"iterations" jsonschema:"default=16,minimum=1,maximum=58,title=Iterations" jsonschema_description:"The SCrypt iterations to be used"` + BlockSize int `koanf:"block_size" json:"block_size" jsonschema:"default=8,minimum=1,maximum=36028797018963967,title=Key Length" jsonschema_description:"The SCrypt block size to be used"` + Parallelism int `koanf:"parallelism" json:"parallelism" jsonschema:"default=1,minimum=1,maximum=1073741823,title=Key Length" jsonschema_description:"The SCrypt parallelism factor to be used"` + KeyLength int `koanf:"key_length" json:"key_length" jsonschema:"default=32,minimum=1,maximum=137438953440,title=Key Length" jsonschema_description:"The SCrypt key length to be used"` + SaltLength int `koanf:"salt_length" json:"salt_length" jsonschema:"default=16,minimum=8,maximum=1024,title=Salt Length" jsonschema_description:"The SCrypt salt length to be used"` } -// LDAPAuthenticationBackend represents the configuration related to LDAP server. -type LDAPAuthenticationBackend struct { - Address *AddressLDAP `koanf:"address"` - Implementation string `koanf:"implementation"` - Timeout time.Duration `koanf:"timeout"` - StartTLS bool `koanf:"start_tls"` - TLS *TLSConfig `koanf:"tls"` +// AuthenticationBackendLDAP represents the configuration related to LDAP server. +type AuthenticationBackendLDAP struct { + Address *AddressLDAP `koanf:"address" json:"address" jsonschema:"title=Address" jsonschema_description:"The address of the LDAP directory server"` + Implementation string `koanf:"implementation" json:"implementation" jsonschema:"default=custom,enum=custom,enum=activedirectory,enum=rfc2307bis,enum=freeipa,enum=lldap,enum=glauth,title=Implementation" jsonschema_description:"The implementation which mostly decides the default values"` + Timeout time.Duration `koanf:"timeout" json:"timeout" jsonschema:"default=5 seconds,title=Timeout" jsonschema_description:"The LDAP directory server connection timeout"` + StartTLS bool `koanf:"start_tls" json:"start_tls" jsonschema:"default=false,title=StartTLS" jsonschema_description:"Enables the use of StartTLS"` + TLS *TLS `koanf:"tls" json:"tls" jsonschema:"title=TLS" jsonschema_description:"The LDAP directory server TLS connection properties"` - BaseDN string `koanf:"base_dn"` + BaseDN string `koanf:"base_dn" json:"base_dn" jsonschema:"title=Base DN" jsonschema_description:"The base for all directory server operations"` - AdditionalUsersDN string `koanf:"additional_users_dn"` - UsersFilter string `koanf:"users_filter"` + AdditionalUsersDN string `koanf:"additional_users_dn" json:"additional_users_dn" jsonschema:"title=Additional User Base" jsonschema_description:"The base in addition to the Base DN for all directory server operations for users"` + UsersFilter string `koanf:"users_filter" json:"users_filter" jsonschema:"title=Users Filter" jsonschema_description:"The LDAP filter used to search for user objects"` - AdditionalGroupsDN string `koanf:"additional_groups_dn"` - GroupsFilter string `koanf:"groups_filter"` + AdditionalGroupsDN string `koanf:"additional_groups_dn" json:"additional_groups_dn" jsonschema:"title=Additional Group Base" jsonschema_description:"The base in addition to the Base DN for all directory server operations for groups"` + GroupsFilter string `koanf:"groups_filter" json:"groups_filter" jsonschema:"title=Groups Filter" jsonschema_description:"The LDAP filter used to search for group objects"` GroupSearchMode string `koanf:"group_search_mode"` - Attributes LDAPAuthenticationAttributes `koanf:"attributes"` + Attributes AuthenticationBackendLDAPAttributes `koanf:"attributes" json:"attributes"` - PermitReferrals bool `koanf:"permit_referrals"` - PermitUnauthenticatedBind bool `koanf:"permit_unauthenticated_bind"` - PermitFeatureDetectionFailure bool `koanf:"permit_feature_detection_failure"` + PermitReferrals bool `koanf:"permit_referrals" json:"permit_referrals" jsonschema:"default=false,title=Permit Referrals" jsonschema_description:"Enables chasing LDAP referrals"` + PermitUnauthenticatedBind bool `koanf:"permit_unauthenticated_bind" json:"permit_unauthenticated_bind" jsonschema:"default=false,title=Permit Unauthenticated Bind" jsonschema_description:"Enables omission of the password to perform an unauthenticated bind"` + PermitFeatureDetectionFailure bool `koanf:"permit_feature_detection_failure" json:"permit_feature_detection_failure" jsonschema:"default=false,title=Permit Feature Detection Failure" jsonschema_description:"Enables failures when detecting directory server features using the Root DSE lookup"` - User string `koanf:"user"` - Password string `koanf:"password"` + User string `koanf:"user" json:"user" jsonschema:"title=User" jsonschema_description:"The user distinguished name for LDAP binding"` + Password string `koanf:"password" json:"password" jsonschema:"title=Password" jsonschema_description:"The password for LDAP authenticated binding"` } -// LDAPAuthenticationAttributes represents the configuration related to LDAP server attributes. -type LDAPAuthenticationAttributes struct { - DistinguishedName string `koanf:"distinguished_name"` - Username string `koanf:"username"` - DisplayName string `koanf:"display_name"` - Mail string `koanf:"mail"` - MemberOf string `koanf:"member_of"` - GroupName string `koanf:"group_name"` +// AuthenticationBackendLDAPAttributes represents the configuration related to LDAP server attributes. +type AuthenticationBackendLDAPAttributes struct { + DistinguishedName string `koanf:"distinguished_name" json:"distinguished_name" jsonschema:"title=Attribute: Distinguished Name" jsonschema_description:"The directory server attribute which contains the distinguished name for all objects"` + Username string `koanf:"username" json:"username" jsonschema:"title=Attribute: User Username" jsonschema_description:"The directory server attribute which contains the username for all users"` + DisplayName string `koanf:"display_name" json:"display_name" jsonschema:"title=Attribute: User Display Name" jsonschema_description:"The directory server attribute which contains the display name for all users"` + Mail string `koanf:"mail" json:"mail" jsonschema:"title=Attribute: User Mail" jsonschema_description:"The directory server attribute which contains the mail address for all users and groups"` + MemberOf string `koanf:"member_of" jsonschema:"title=Attribute: Member Of" jsonschema_description:"The directory server attribute which contains the objects that an object is a member of"` + GroupName string `koanf:"group_name" json:"group_name" jsonschema:"title=Attribute: Group Name" jsonschema_description:"The directory server attribute which contains the group name for all groups"` } // DefaultPasswordConfig represents the default configuration related to Argon2id hashing. -var DefaultPasswordConfig = Password{ +var DefaultPasswordConfig = AuthenticationBackendFilePassword{ Algorithm: argon2, - Argon2: Argon2Password{ + Argon2: AuthenticationBackendFilePasswordArgon2{ Variant: argon2id, Iterations: 3, Memory: 64 * 1024, @@ -141,21 +152,21 @@ var DefaultPasswordConfig = Password{ KeyLength: 32, SaltLength: 16, }, - SHA2Crypt: SHA2CryptPassword{ + SHA2Crypt: AuthenticationBackendFilePasswordSHA2Crypt{ Variant: sha512, Iterations: 50000, SaltLength: 16, }, - PBKDF2: PBKDF2Password{ + PBKDF2: AuthenticationBackendFilePasswordPBKDF2{ Variant: sha512, Iterations: 310000, SaltLength: 16, }, - BCrypt: BCryptPassword{ + BCrypt: AuthenticationBackendFilePasswordBCrypt{ Variant: "standard", Cost: 12, }, - SCrypt: SCryptPassword{ + SCrypt: AuthenticationBackendFilePasswordSCrypt{ Iterations: 16, BlockSize: 8, Parallelism: 1, @@ -165,16 +176,16 @@ var DefaultPasswordConfig = Password{ } // DefaultCIPasswordConfig represents the default configuration related to Argon2id hashing for CI. -var DefaultCIPasswordConfig = Password{ +var DefaultCIPasswordConfig = AuthenticationBackendFilePassword{ Algorithm: argon2, - Argon2: Argon2Password{ + Argon2: AuthenticationBackendFilePasswordArgon2{ Iterations: 3, Memory: 64, Parallelism: 4, KeyLength: 32, SaltLength: 16, }, - SHA2Crypt: SHA2CryptPassword{ + SHA2Crypt: AuthenticationBackendFilePasswordSHA2Crypt{ Variant: sha512, Iterations: 50000, SaltLength: 16, @@ -182,26 +193,26 @@ var DefaultCIPasswordConfig = Password{ } // DefaultLDAPAuthenticationBackendConfigurationImplementationCustom represents the default LDAP config. -var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = AuthenticationBackendLDAP{ GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ Username: ldapAttrUserID, DisplayName: ldapAttrDisplayName, Mail: ldapAttrMail, GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory represents the default LDAP config for the LDAPImplementationActiveDirectory Implementation. -var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = AuthenticationBackendLDAP{ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:microsoft-nt})))", GroupsFilter: "(&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912)))", GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ DistinguishedName: ldapAttrDistinguishedName, Username: ldapAttrSAMAccountName, DisplayName: ldapAttrDisplayName, @@ -210,17 +221,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis represents the default LDAP config for the LDAPImplementationRFC2307bis Implementation. -var DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis = AuthenticationBackendLDAP{ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(|(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))", GroupsFilter: "(&(|(member={dn})(uniqueMember={dn}))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=groupOfMembers))(!(pwdReset=TRUE)))", GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ Username: ldapAttrUserID, DisplayName: ldapAttrDisplayName, Mail: ldapAttrMail, @@ -228,17 +239,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis = LDAP GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA represents the default LDAP config for the LDAPImplementationFreeIPA Implementation. -var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = AuthenticationBackendLDAP{ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized})))", GroupsFilter: "(&(member={dn})(objectClass=groupOfNames))", GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ Username: ldapAttrUserID, DisplayName: ldapAttrDisplayName, Mail: ldapAttrMail, @@ -246,19 +257,19 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAut GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP represents the default LDAP config for the LDAPImplementationLLDAP Implementation. -var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = AuthenticationBackendLDAP{ AdditionalUsersDN: "OU=people", AdditionalGroupsDN: "OU=groups", UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))", GroupsFilter: "(&(member={dn})(objectClass=groupOfUniqueNames))", GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ Username: ldapAttrUserID, DisplayName: ldapAttrCommonName, Mail: ldapAttrMail, @@ -266,17 +277,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = LDAPAuthe GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth represents the default LDAP config for the LDAPImplementationGLAuth Implementation. -var DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth = LDAPAuthenticationBackend{ +var DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth = AuthenticationBackendLDAP{ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=posixAccount)(!(accountStatus=inactive)))", GroupsFilter: "(&(uniqueMember={dn})(objectClass=posixGroup))", GroupSearchMode: ldapGroupSearchModeFilter, - Attributes: LDAPAuthenticationAttributes{ + Attributes: AuthenticationBackendLDAPAttributes{ Username: ldapAttrCommonName, DisplayName: ldapAttrDescription, Mail: ldapAttrMail, @@ -284,7 +295,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth = LDAPAuth GroupName: ldapAttrCommonName, }, Timeout: time.Second * 5, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } diff --git a/internal/configuration/schema/configuration.go b/internal/configuration/schema/configuration.go index 20dbce83c..3761aad3d 100644 --- a/internal/configuration/schema/configuration.go +++ b/internal/configuration/schema/configuration.go @@ -2,26 +2,26 @@ package schema // Configuration object extracted from YAML configuration file. type Configuration struct { - Theme string `koanf:"theme"` - CertificatesDirectory string `koanf:"certificates_directory"` - JWTSecret string `koanf:"jwt_secret"` - DefaultRedirectionURL string `koanf:"default_redirection_url"` - Default2FAMethod string `koanf:"default_2fa_method"` + Theme string `koanf:"theme" json:"theme" jsonschema:"default=light,enum=auto,enum=light,enum=dark,enum=grey,title=Theme Name" jsonschema_description:"The name of the theme to apply to the web UI"` + CertificatesDirectory string `koanf:"certificates_directory" json:"certificates_directory" jsonschema:"title=Certificates Directory Path" jsonschema_description:"The path to a directory which is used to determine the certificates that are trusted"` + JWTSecret string `koanf:"jwt_secret" json:"jwt_secret" jsonschema:"title=Secret Key for JWT's" jsonschema_description:"Used for signing HS256 JWT's for identity verification"` + DefaultRedirectionURL string `koanf:"default_redirection_url" json:"default_redirection_url" jsonschema:"title=The default redirection URL" jsonschema_description:"Used to redirect users when they visit the portal directly"` + Default2FAMethod string `koanf:"default_2fa_method" json:"default_2fa_method" jsonschema:"enum=totp,enum=webauthn,enum=mobile_push,title=Default 2FA method" jsonschema_description:"When a user logs in for the first time this is the 2FA method configured for them"` - Log LogConfiguration `koanf:"log"` - IdentityProviders IdentityProviders `koanf:"identity_providers"` - AuthenticationBackend AuthenticationBackend `koanf:"authentication_backend"` - Session SessionConfiguration `koanf:"session"` - TOTP TOTPConfiguration `koanf:"totp"` - DuoAPI DuoAPIConfiguration `koanf:"duo_api"` - AccessControl AccessControlConfiguration `koanf:"access_control"` - NTP NTPConfiguration `koanf:"ntp"` - Regulation RegulationConfiguration `koanf:"regulation"` - Storage StorageConfiguration `koanf:"storage"` - Notifier NotifierConfiguration `koanf:"notifier"` - Server ServerConfiguration `koanf:"server"` - Telemetry TelemetryConfig `koanf:"telemetry"` - WebAuthn WebAuthnConfiguration `koanf:"webauthn"` - PasswordPolicy PasswordPolicyConfiguration `koanf:"password_policy"` - PrivacyPolicy PrivacyPolicy `koanf:"privacy_policy"` + Log Log `koanf:"log" json:"log" jsonschema:"title=Log" jsonschema_description:"Logging Configuration"` + IdentityProviders IdentityProviders `koanf:"identity_providers" json:"identity_providers" jsonschema:"title=Identity Providers" jsonschema_description:"Identity Providers Configuration"` + AuthenticationBackend AuthenticationBackend `koanf:"authentication_backend" json:"authentication_backend" jsonschema:"title=Authentication Backend" jsonschema_description:"Authentication Backend Configuration"` + Session Session `koanf:"session" json:"session" jsonschema:"title=Session" jsonschema_description:"Session Configuration"` + TOTP TOTP `koanf:"totp" json:"totp" jsonschema:"title=TOTP" jsonschema_description:"Time-based One Time Password Configuration"` + DuoAPI DuoAPI `koanf:"duo_api" json:"duo_api" jsonschema:"title=Duo API" jsonschema_description:"Duo API Configuration"` + AccessControl AccessControl `koanf:"access_control" json:"access_control" jsonschema:"title=Access Control" jsonschema_description:"Access Control Configuration"` + NTP NTP `koanf:"ntp" json:"ntp" jsonschema:"title=NTP" jsonschema_description:"Network Time Protocol Configuration"` + Regulation Regulation `koanf:"regulation" json:"regulation" jsonschema:"title=Regulation" jsonschema_description:"Regulation Configuration"` + Storage Storage `koanf:"storage" json:"storage" jsonschema:"title=Storage" jsonschema_description:"Storage Configuration"` + Notifier Notifier `koanf:"notifier" json:"notifier" jsonschema:"title=Notifier" jsonschema_description:"Notifier Configuration"` + Server Server `koanf:"server" json:"server" jsonschema:"title=Server" jsonschema_description:"Server Configuration"` + Telemetry Telemetry `koanf:"telemetry" json:"telemetry" jsonschema:"title=Telemetry" jsonschema_description:"Telemetry Configuration"` + WebAuthn WebAuthn `koanf:"webauthn" json:"webauthn" jsonschema:"title=WebAuthn" jsonschema_description:"WebAuthn Configuration"` + PasswordPolicy PasswordPolicy `koanf:"password_policy" json:"password_policy" jsonschema:"title=Password Policy" jsonschema_description:"Password Policy Configuration"` + PrivacyPolicy PrivacyPolicy `koanf:"privacy_policy" json:"privacy_policy" jsonschema:"title=Privacy Policy" jsonschema_description:"Privacy Policy Configuration"` } diff --git a/internal/configuration/schema/duo.go b/internal/configuration/schema/duo.go index 75e383d3e..aa3207b59 100644 --- a/internal/configuration/schema/duo.go +++ b/internal/configuration/schema/duo.go @@ -1,10 +1,10 @@ package schema -// DuoAPIConfiguration represents the configuration related to Duo API. -type DuoAPIConfiguration struct { - Disable bool `koanf:"disable"` - Hostname string `koanf:"hostname"` - IntegrationKey string `koanf:"integration_key"` - SecretKey string `koanf:"secret_key"` - EnableSelfEnrollment bool `koanf:"enable_self_enrollment"` +// DuoAPI represents the configuration related to Duo API. +type DuoAPI struct { + Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disable the Duo API integration"` + Hostname string `koanf:"hostname" json:"hostname" jsonschema:"format=hostname,title=Hostname" jsonschema_description:"The Hostname provided by your Duo API dashboard"` + IntegrationKey string `koanf:"integration_key" json:"integration_key" jsonschema:"title=Integration Key" jsonschema_description:"The Integration Key provided by your Duo API dashboard"` + SecretKey string `koanf:"secret_key" json:"secret_key" jsonschema:"title=Secret Key" jsonschema_description:"The Secret Key provided by your Duo API dashboard"` + EnableSelfEnrollment bool `koanf:"enable_self_enrollment" json:"enable_self_enrollment" jsonschema:"default=false,title=Enable Self Enrollment" jsonschema_description:"Enable the Self Enrollment flow"` } diff --git a/internal/configuration/schema/identity_providers.go b/internal/configuration/schema/identity_providers.go index 9b8955077..33eb284d7 100644 --- a/internal/configuration/schema/identity_providers.go +++ b/internal/configuration/schema/identity_providers.go @@ -8,34 +8,34 @@ import ( // IdentityProviders represents the Identity Providers configuration for Authelia. type IdentityProviders struct { - OIDC *OpenIDConnect `koanf:"oidc"` + OIDC *IdentityProvidersOpenIDConnect `koanf:"oidc" json:"oidc"` } -// OpenIDConnect configuration for OpenID Connect 1.0. -type OpenIDConnect struct { - HMACSecret string `koanf:"hmac_secret"` - IssuerPrivateKeys []JWK `koanf:"issuer_private_keys"` +// IdentityProvidersOpenIDConnect represents the configuration for OpenID Connect 1.0. +type IdentityProvidersOpenIDConnect struct { + HMACSecret string `koanf:"hmac_secret" json:"hmac_secret" jsonschema:"title=HMAC Secret" jsonschema_description:"The HMAC Secret used to sign Access Tokens"` + IssuerPrivateKeys []JWK `koanf:"issuer_private_keys" json:"issuer_private_keys" jsonschema:"title=Issuer Private Keys" jsonschema_description:"The Private Keys used to sign ID Tokens"` - IssuerCertificateChain X509CertificateChain `koanf:"issuer_certificate_chain"` - IssuerPrivateKey *rsa.PrivateKey `koanf:"issuer_private_key"` + IssuerCertificateChain X509CertificateChain `koanf:"issuer_certificate_chain" json:"issuer_certificate_chain" jsonschema:"title=Issuer Certificate Chain" jsonschema_description:"The Issuer Certificate Chain with an RSA Public Key used to sign ID Tokens"` + IssuerPrivateKey *rsa.PrivateKey `koanf:"issuer_private_key" json:"issuer_private_key" jsonschema:"title=Issuer Private Key" jsonschema_description:"The Issuer Private Key with an RSA Private Key used to sign ID Tokens"` - AccessTokenLifespan time.Duration `koanf:"access_token_lifespan"` - AuthorizeCodeLifespan time.Duration `koanf:"authorize_code_lifespan"` - IDTokenLifespan time.Duration `koanf:"id_token_lifespan"` - RefreshTokenLifespan time.Duration `koanf:"refresh_token_lifespan"` + AccessTokenLifespan time.Duration `koanf:"access_token_lifespan" json:"access_token_lifespan" jsonschema:"default=60 minutes,title=Access Token Lifespan" jsonschema_description:"The duration an Access Token is valid for"` + AuthorizeCodeLifespan time.Duration `koanf:"authorize_code_lifespan" json:"authorize_code_lifespan" jsonschema:"default=1 minute,title=Authorize Code Lifespan" jsonschema_description:"The duration an Authorization Code is valid for"` + IDTokenLifespan time.Duration `koanf:"id_token_lifespan" json:"id_token_lifespan" jsonschema:"default=60 minutes,title=ID Token Lifespan" jsonschema_description:"The duration an ID Token is valid for"` + RefreshTokenLifespan time.Duration `koanf:"refresh_token_lifespan" json:"refresh_token_lifespan" jsonschema:"default=90 minutes,title=Refresh Token Lifespan" jsonschema_description:"The duration a Refresh Token is valid for"` - EnableClientDebugMessages bool `koanf:"enable_client_debug_messages"` - MinimumParameterEntropy int `koanf:"minimum_parameter_entropy"` + EnableClientDebugMessages bool `koanf:"enable_client_debug_messages" json:"enable_client_debug_messages" jsonschema:"default=false,title=Enable Client Debug Messages" jsonschema_description:"Enables additional debug messages for clients"` + MinimumParameterEntropy int `koanf:"minimum_parameter_entropy" json:"minimum_parameter_entropy" jsonschema:"default=8,minimum=-1,title=Minimum Parameter Entropy" jsonschema_description:"The minimum entropy of the nonce parameter"` - EnforcePKCE string `koanf:"enforce_pkce"` - EnablePKCEPlainChallenge bool `koanf:"enable_pkce_plain_challenge"` + EnforcePKCE string `koanf:"enforce_pkce" json:"enforce_pkce" jsonschema:"default=public_clients_only,enum=public_clients_only,enum=never,enum=always,title=Enforce PKCE" jsonschema_description:"Controls enforcement of the use of Proof Key for Code Exchange on all clients"` + EnablePKCEPlainChallenge bool `koanf:"enable_pkce_plain_challenge" json:"enable_pkce_plain_challenge" jsonschema:"default=false,title=Enable PKCE Plain Challenge" jsonschema_description:"Enables use of the discouraged plain Proof Key for Code Exchange challenges"` - PAR OpenIDConnectPAR `koanf:"pushed_authorizations"` - CORS OpenIDConnectCORS `koanf:"cors"` + PAR IdentityProvidersOpenIDConnectPAR `koanf:"pushed_authorizations" json:"pushed_authorizations" jsonschema:"title=Pushed Authorizations" jsonschema_description:"Configuration options for Pushed Authorization Requests"` + CORS IdentityProvidersOpenIDConnectCORS `koanf:"cors" json:"cors" jsonschema:"title=CORS" jsonschema_description:"Configuration options for Cross-Origin Request Sharing"` - Clients []OpenIDConnectClient `koanf:"clients"` + Clients []IdentityProvidersOpenIDConnectClient `koanf:"clients" json:"clients" jsonschema:"title=Clients" jsonschema_description:"OpenID Connect 1.0 clients registry"` - Discovery OpenIDConnectDiscovery // MetaData value. Not configurable by users. + Discovery OpenIDConnectDiscovery `json:"-"` // MetaData value. Not configurable by users. } // OpenIDConnectDiscovery is information discovered during validation reused for the discovery handlers. @@ -47,68 +47,68 @@ type OpenIDConnectDiscovery struct { RequestObjectSigningAlgs []string } -// OpenIDConnectPAR represents an OpenID Connect 1.0 PAR config. -type OpenIDConnectPAR struct { - Enforce bool `koanf:"enforce"` - ContextLifespan time.Duration `koanf:"context_lifespan"` +// IdentityProvidersOpenIDConnectPAR represents an OpenID Connect 1.0 PAR config. +type IdentityProvidersOpenIDConnectPAR struct { + Enforce bool `koanf:"enforce" json:"enforce" jsonschema:"default=false,title=Enforce" jsonschema_description:"Enforce the use of PAR for all requests on all clients"` + ContextLifespan time.Duration `koanf:"context_lifespan" json:"context_lifespan" jsonschema:"default=5 minutes,title=Context Lifespan" jsonschema_description:"How long a PAR context is valid for"` } -// OpenIDConnectCORS represents an OpenID Connect 1.0 CORS config. -type OpenIDConnectCORS struct { - Endpoints []string `koanf:"endpoints"` - AllowedOrigins []url.URL `koanf:"allowed_origins"` +// IdentityProvidersOpenIDConnectCORS represents an OpenID Connect 1.0 CORS config. +type IdentityProvidersOpenIDConnectCORS struct { + Endpoints []string `koanf:"endpoints" json:"endpoints" jsonschema:"uniqueItems,enum=authorization,enum=pushed-authorization-request,enum=token,enum=introspection,enum=revocation,enum=userinfo,title=Endpoints" jsonschema_description:"List of endpoints to enable CORS handling for"` + AllowedOrigins []url.URL `koanf:"allowed_origins" json:"allowed_origins" jsonschema:"format=uri,title=Allowed Origins" jsonschema_description:"List of arbitrary allowed origins for CORS requests"` - AllowedOriginsFromClientRedirectURIs bool `koanf:"allowed_origins_from_client_redirect_uris"` + AllowedOriginsFromClientRedirectURIs bool `koanf:"allowed_origins_from_client_redirect_uris" json:"allowed_origins_from_client_redirect_uris" jsonschema:"default=false,title=Allowed Origins From Client Redirect URIs" jsonschema_description:"Automatically include the redirect URIs from the registered clients"` } -// OpenIDConnectClient represents a configuration for an OpenID Connect 1.0 client. -type OpenIDConnectClient struct { - ID string `koanf:"id"` - Description string `koanf:"description"` - Secret *PasswordDigest `koanf:"secret"` - SectorIdentifier url.URL `koanf:"sector_identifier"` - Public bool `koanf:"public"` +// IdentityProvidersOpenIDConnectClient represents a configuration for an OpenID Connect 1.0 client. +type IdentityProvidersOpenIDConnectClient struct { + ID string `koanf:"id" json:"id" jsonschema:"required,minLength=1,title=ID" jsonschema_description:"The Client ID"` + Description string `koanf:"description" json:"description" jsonschema:"title=Description" jsonschema_description:"The Client Description for End-Users"` + Secret *PasswordDigest `koanf:"secret" json:"secret" jsonschema:"title=Secret" jsonschema_description:"The Client Secret for Client Authentication"` + SectorIdentifier url.URL `koanf:"sector_identifier" json:"sector_identifier" jsonschema:"title=Sector Identifier" jsonschema_description:"The Client Sector Identifier for Privacy Isolation"` + Public bool `koanf:"public" json:"public" jsonschema:"default=false,title=Public" jsonschema_description:"Enables the Public Client Type"` - RedirectURIs []string `koanf:"redirect_uris"` + RedirectURIs IdentityProvidersOpenIDConnectClientRedirectURIs `koanf:"redirect_uris" json:"redirect_uris" jsonschema:"required,title=Redirect URIs" jsonschema_description:"List of authorized redirect URIs"` - Audience []string `koanf:"audience"` - Scopes []string `koanf:"scopes"` - GrantTypes []string `koanf:"grant_types"` - ResponseTypes []string `koanf:"response_types"` - ResponseModes []string `koanf:"response_modes"` + Audience []string `koanf:"audience" json:"audience" jsonschema:"uniqueItems,title=Audience" jsonschema_description:"List of authorized audiences"` + Scopes []string `koanf:"scopes" json:"scopes" jsonschema:"required,enum=openid,enum=offline_access,enum=groups,enum=email,enum=profile,uniqueItems,title=Scopes" jsonschema_description:"The Scopes this client is allowed request and be granted"` + GrantTypes []string `koanf:"grant_types" json:"grant_types" jsonschema:"enum=authorization_code,enum=implicit,enum=refresh_token,uniqueItems,title=Grant Types" jsonschema_description:"The Grant Types this client is allowed to use for the protected endpoints"` + ResponseTypes []string `koanf:"response_types" json:"response_types" jsonschema:"enum=code,enum=id_token token,enum=id_token,enum=token,enum=code token,enum=code id_token,enum=code id_token token,uniqueItems,title=Response Types" jsonschema_description:"The Response Types the client is authorized to request"` + ResponseModes []string `koanf:"response_modes" json:"response_modes" jsonschema:"enum=form_post,enum=query,enum=fragment,uniqueItems,title=Response Modes" jsonschema_description:"The Response Modes this client is authorized request"` - Policy string `koanf:"authorization_policy"` + Policy string `koanf:"authorization_policy" json:"authorization_policy" jsonschema:"title=Authorization Policy" jsonschema_description:"The Authorization Policy to apply to this client"` - ConsentMode string `koanf:"consent_mode"` - ConsentPreConfiguredDuration *time.Duration `koanf:"pre_configured_consent_duration"` + ConsentMode string `koanf:"consent_mode" json:"consent_mode" jsonschema:"enum=auto,enum=explicit,enum=implicit,enum=pre-configured,title=Consent Mode" jsonschema_description:"The Consent Mode used for this client"` + ConsentPreConfiguredDuration *time.Duration `koanf:"pre_configured_consent_duration" json:"pre_configured_consent_duration" jsonschema:"default=7 days,title=Pre-Configured Consent Duration" jsonschema_description:"The Pre-Configured Consent Duration when using Consent Mode pre-configured for this client"` - EnforcePAR bool `koanf:"enforce_par"` - EnforcePKCE bool `koanf:"enforce_pkce"` + EnforcePAR bool `koanf:"enforce_par" json:"enforce_par" jsonschema:"default=false,title=Enforce PAR" jsonschema_description:"Enforces Pushed Authorization Requests for this client"` + EnforcePKCE bool `koanf:"enforce_pkce" json:"enforce_pkce" jsonschema:"default=false,title=Enforce PKCE" jsonschema_description:"Enforces Proof Key for Code Exchange for this client"` - PKCEChallengeMethod string `koanf:"pkce_challenge_method"` + PKCEChallengeMethod string `koanf:"pkce_challenge_method" json:"pkce_challenge_method" jsonschema:"enum=plain,enum=S256,title=PKCE Challenge Method" jsonschema_description:"The PKCE Challenge Method enforced on this client"` - IDTokenSigningAlg string `koanf:"id_token_signing_alg"` - IDTokenSigningKeyID string `koanf:"id_token_signing_key_id"` - UserinfoSigningAlg string `koanf:"userinfo_signing_alg"` - UserinfoSigningKeyID string `koanf:"userinfo_signing_key_id"` - RequestObjectSigningAlg string `koanf:"request_object_signing_alg"` - TokenEndpointAuthSigningAlg string `koanf:"token_endpoint_auth_signing_alg"` + IDTokenSigningAlg string `koanf:"id_token_signing_alg" json:"id_token_signing_alg" jsonschema:"eneum=none,enum=RS256,enum=RS384,enum=RS512,enum=ES256,enum=ES384,enum=ES512,enum=PS256,enum=PS384,enum=PS512,title=ID Token Signing Algorithm" jsonschema_description:"The algorithm (JWA) this client uses to sign ID Tokens"` + IDTokenSigningKeyID string `koanf:"id_token_signing_key_id" json:"id_token_signing_key_id" jsonschema:"title=ID Token Signing Key ID" jsonschema_description:"The Key ID this client uses to sign ID Tokens (overrides the 'id_token_signing_alg')"` + UserinfoSigningAlg string `koanf:"userinfo_signing_alg" json:"userinfo_signing_alg" jsonschema:"enum=none,enum=RS256,enum=RS384,enum=RS512,enum=ES256,enum=ES384,enum=ES512,enum=PS256,enum=PS384,enum=PS512,title=Userinfo Signing Algorithm" jsonschema_description:"The Userinfo Endpoint Signing Algorithm this client uses"` + UserinfoSigningKeyID string `koanf:"userinfo_signing_key_id" json:"userinfo_signing_key_id" jsonschema:"title=Userinfo Signing Key ID" jsonschema_description:"The Key ID this client uses to sign the userinfo responses (overrides the 'userinfo_token_signing_alg')"` + RequestObjectSigningAlg string `koanf:"request_object_signing_alg" json:"request_object_signing_alg" jsonschema:"enum=RS256,enum=RS384,enum=RS512,enum=ES256,enum=ES384,enum=ES512,enum=PS256,enum=PS384,enum=PS512,title=Request Object Signing Algorithm" jsonschema_description:"The Request Object Signing Algorithm the provider accepts for this client"` + TokenEndpointAuthSigningAlg string `koanf:"token_endpoint_auth_signing_alg" json:"token_endpoint_auth_signing_alg" jsonschema:"enum=HS256,enum=HS384,enum=HS512,enum=RS256,enum=RS384,enum=RS512,enum=ES256,enum=ES384,enum=ES512,enum=PS256,enum=PS384,enum=PS512,title=Token Endpoint Auth Signing Algorithm" jsonschema_description:"The Token Endpoint Auth Signing Algorithm the provider accepts for this client"` - TokenEndpointAuthMethod string `koanf:"token_endpoint_auth_method"` + TokenEndpointAuthMethod string `koanf:"token_endpoint_auth_method" json:"token_endpoint_auth_method" jsonschema:"enum=none,enum=client_secret_post,enum=client_secret_basic,enum=private_key_jwt,enum=client_secret_jwt,title=Token Endpoint Auth Method" jsonschema_description:"The Token Endpoint Auth Method enforced by the provider for this client"` - PublicKeys OpenIDConnectClientPublicKeys `koanf:"public_keys"` + PublicKeys IdentityProvidersOpenIDConnectClientPublicKeys `koanf:"public_keys" json:"public_keys,omitempty" jsonschema:"title=Public Keys" jsonschema_description:"Public Key options used to validate request objects and the 'private_key_jwt' client authentication method for this client"` - Discovery OpenIDConnectDiscovery + Discovery OpenIDConnectDiscovery `json:"-"` // MetaData value. Not configurable by users. } -// OpenIDConnectClientPublicKeys represents the Client Public Keys configuration for an OpenID Connect 1.0 client. -type OpenIDConnectClientPublicKeys struct { - URI *url.URL `koanf:"uri"` - Values []JWK `koanf:"values"` +// IdentityProvidersOpenIDConnectClientPublicKeys represents the Client Public Keys configuration for an OpenID Connect 1.0 client. +type IdentityProvidersOpenIDConnectClientPublicKeys struct { + URI *url.URL `koanf:"uri" json:"uri" jsonschema:"oneof_required=URI,title=URI" jsonschema_description:"URI of the JWKS endpoint which contains the Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client"` + Values []JWK `koanf:"values" json:"values" jsonschema:"oneof_required=Values,title=Values" jsonschema_description:"List of arbitrary Public Keys used to validate request objects and the 'private_key_jwt' client authentication method for this client"` } // DefaultOpenIDConnectConfiguration contains defaults for OIDC. -var DefaultOpenIDConnectConfiguration = OpenIDConnect{ +var DefaultOpenIDConnectConfiguration = IdentityProvidersOpenIDConnect{ AccessTokenLifespan: time.Hour, AuthorizeCodeLifespan: time.Minute, IDTokenLifespan: time.Hour, @@ -119,7 +119,7 @@ var DefaultOpenIDConnectConfiguration = OpenIDConnect{ var defaultOIDCClientConsentPreConfiguredDuration = time.Hour * 24 * 7 // DefaultOpenIDConnectClientConfiguration contains defaults for OIDC Clients. -var DefaultOpenIDConnectClientConfiguration = OpenIDConnectClient{ +var DefaultOpenIDConnectClientConfiguration = IdentityProvidersOpenIDConnectClient{ Policy: "two_factor", Scopes: []string{"openid", "groups", "profile", "email"}, ResponseTypes: []string{"code"}, diff --git a/internal/configuration/schema/keys.go b/internal/configuration/schema/keys.go index df820a3ce..853368f64 100644 --- a/internal/configuration/schema/keys.go +++ b/internal/configuration/schema/keys.go @@ -132,22 +132,21 @@ var Keys = []string{ "authentication_backend.ldap.permit_feature_detection_failure", "authentication_backend.ldap.user", "authentication_backend.ldap.password", - "session.secret", "session.name", - "session.domain", "session.same_site", "session.expiration", "session.inactivity", "session.remember_me", "session", + "session.secret", "session.cookies", "session.cookies[].name", - "session.cookies[].domain", "session.cookies[].same_site", "session.cookies[].expiration", "session.cookies[].inactivity", "session.cookies[].remember_me", "session.cookies[]", + "session.cookies[].domain", "session.cookies[].authelia_url", "session.redis.host", "session.redis.port", @@ -165,11 +164,12 @@ var Keys = []string{ "session.redis.high_availability.sentinel_name", "session.redis.high_availability.sentinel_username", "session.redis.high_availability.sentinel_password", + "session.redis.high_availability.route_by_latency", + "session.redis.high_availability.route_randomly", "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", + "session.domain", "totp.disable", "totp.issuer", "totp.algorithm", diff --git a/internal/configuration/schema/log.go b/internal/configuration/schema/log.go index 0678d860f..a1e170e01 100644 --- a/internal/configuration/schema/log.go +++ b/internal/configuration/schema/log.go @@ -1,15 +1,15 @@ package schema -// LogConfiguration represents the logging configuration. -type LogConfiguration struct { - Level string `koanf:"level"` - Format string `koanf:"format"` - FilePath string `koanf:"file_path"` - KeepStdout bool `koanf:"keep_stdout"` +// Log represents the logging configuration. +type Log struct { + Level string `koanf:"level" json:"level" jsonschema:"enum=error,enum=warn,enum=info,enum=debug,enum=trace,title=Level" jsonschema_description:"The minimum Level a Log message must be before it's added to the log'"` + Format string `koanf:"format" json:"format" jsonschema:"enum=json,enum=text,title=Format" jsonschema_description:"The Format of Log messages"` + FilePath string `koanf:"file_path" json:"file_path" jsonschema:"title=File Path" jsonschema_description:"The File Path to save the logs to instead of sending them to stdout"` + KeepStdout bool `koanf:"keep_stdout" json:"keep_stdout" jsonschema:"default=false,title=Keep Stdout" jsonschema_description:"Enables keeping stdout when using the File Path option"` } // DefaultLoggingConfiguration is the default logging configuration. -var DefaultLoggingConfiguration = LogConfiguration{ +var DefaultLoggingConfiguration = Log{ Level: "info", Format: "text", } diff --git a/internal/configuration/schema/notifier.go b/internal/configuration/schema/notifier.go index 9a3d862d0..1f711a9d9 100644 --- a/internal/configuration/schema/notifier.go +++ b/internal/configuration/schema/notifier.go @@ -7,49 +7,49 @@ import ( "time" ) -// FileSystemNotifierConfiguration represents the configuration of the notifier writing emails in a file. -type FileSystemNotifierConfiguration struct { - Filename string `koanf:"filename"` +// Notifier represents the configuration of the notifier to use when sending notifications to users. +type Notifier struct { + DisableStartupCheck bool `koanf:"disable_startup_check" json:"disable_startup_check" jsonschema:"default=false,title=Disable Startup Check" jsonschema_description:"Disables the notifier startup checks"` + FileSystem *NotifierFileSystem `koanf:"filesystem" json:"filesystem" jsonschema:"title=File System" jsonschema_description:"The File System notifier"` + SMTP *NotifierSMTP `koanf:"smtp" json:"smtp" jsonschema:"title=SMTP" jsonschema_description:"The SMTP notifier"` + TemplatePath string `koanf:"template_path" json:"template_path" jsonschema:"title=Template Path" jsonschema_description:"The path for notifier template overrides"` } -// SMTPNotifierConfiguration represents the configuration of the SMTP server to send emails with. -type SMTPNotifierConfiguration struct { - Address *AddressSMTP `koanf:"address"` - Timeout time.Duration `koanf:"timeout"` - Username string `koanf:"username"` - Password string `koanf:"password"` - Identifier string `koanf:"identifier"` - Sender mail.Address `koanf:"sender"` - Subject string `koanf:"subject"` - StartupCheckAddress mail.Address `koanf:"startup_check_address"` - DisableRequireTLS bool `koanf:"disable_require_tls"` - DisableHTMLEmails bool `koanf:"disable_html_emails"` - DisableStartTLS bool `koanf:"disable_starttls"` - TLS *TLSConfig `koanf:"tls"` - - // Deprecated: use address instead. - Host string `koanf:"host"` - - // Deprecated: use address instead. - Port int `koanf:"port"` +// NotifierFileSystem represents the configuration of the notifier writing emails in a file. +type NotifierFileSystem struct { + Filename string `koanf:"filename" json:"filename" jsonschema:"title=Filename" jsonschema_description:"The file path of the notifications"` } -// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users. -type NotifierConfiguration struct { - DisableStartupCheck bool `koanf:"disable_startup_check"` - FileSystem *FileSystemNotifierConfiguration `koanf:"filesystem"` - SMTP *SMTPNotifierConfiguration `koanf:"smtp"` - TemplatePath string `koanf:"template_path"` +// NotifierSMTP represents the configuration of the SMTP server to send emails with. +type NotifierSMTP struct { + Address *AddressSMTP `koanf:"address" json:"address" jsonschema:"default=smtp://localhost:25,title=Address" jsonschema_description:"The SMTP server address"` + Timeout time.Duration `koanf:"timeout" json:"timeout" jsonschema:"default=5 seconds,title=Timeout" jsonschema_description:"The SMTP server connection timeout"` + Username string `koanf:"username" json:"username" jsonschema:"title=Username" jsonschema_description:"The username for SMTP authentication"` + Password string `koanf:"password" json:"password" jsonschema:"title=Password" jsonschema_description:"The password for SMTP authentication"` + Identifier string `koanf:"identifier" json:"identifier" jsonschema:"default=localhost,title=Identifier" jsonschema_description:"The identifier used during the HELO/EHLO command"` + Sender mail.Address `koanf:"sender" json:"sender" jsonschema:"title=Sender" jsonschema_description:"The sender used for SMTP"` + Subject string `koanf:"subject" json:"subject" jsonschema:"default=[Authelia] {title},title=Subject" jsonschema_description:"The subject format used"` + StartupCheckAddress mail.Address `koanf:"startup_check_address" json:"startup_check_address" jsonschema:"default=Authelia Test ,title=Startup Check Address" jsonschema_description:"The address used for the recipient in the startup check"` + DisableRequireTLS bool `koanf:"disable_require_tls" json:"disable_require_tls" jsonschema:"default=false,title=Disable Require TLS" jsonschema_description:"Disables the requirement to use TLS"` + DisableHTMLEmails bool `koanf:"disable_html_emails" json:"disable_html_emails" jsonschema:"default=false,title=Disable HTML Emails" jsonschema_description:"Disables the mixed content type of emails and only sends the plaintext version"` + DisableStartTLS bool `koanf:"disable_starttls" json:"disable_starttls" jsonschema:"default=false,title=Disable StartTLS" jsonschema_description:"Disables the opportunistic StartTLS functionality which is useful for bad SMTP servers which advertise support for it but don't actually support it'"` + TLS *TLS `koanf:"tls" json:"tls" jsonschema:"title=TLS" jsonschema_description:"The SMTP server TLS connection properties"` + + // Deprecated: use address instead. + Host string `koanf:"host" json:"host" jsonschema:"deprecated"` + + // Deprecated: use address instead. + Port int `koanf:"port" json:"port" jsonschema:"deprecated"` } // DefaultSMTPNotifierConfiguration represents default configuration parameters for the SMTP notifier. -var DefaultSMTPNotifierConfiguration = SMTPNotifierConfiguration{ +var DefaultSMTPNotifierConfiguration = NotifierSMTP{ Address: &AddressSMTP{Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}}, Timeout: time.Second * 5, Subject: "[Authelia] {title}", Identifier: "localhost", StartupCheckAddress: mail.Address{Name: "Authelia Test", Address: "test@authelia.com"}, - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } diff --git a/internal/configuration/schema/ntp.go b/internal/configuration/schema/ntp.go index 2cfce4b1d..45adc72b8 100644 --- a/internal/configuration/schema/ntp.go +++ b/internal/configuration/schema/ntp.go @@ -5,17 +5,17 @@ import ( "time" ) -// NTPConfiguration represents the configuration related to ntp server. -type NTPConfiguration struct { - Address *AddressUDP `koanf:"address"` - Version int `koanf:"version"` - MaximumDesync time.Duration `koanf:"max_desync"` - DisableStartupCheck bool `koanf:"disable_startup_check"` - DisableFailure bool `koanf:"disable_failure"` +// NTP represents the configuration related to ntp server. +type NTP struct { + Address *AddressUDP `koanf:"address" json:"address"` + Version int `koanf:"version" json:"version" jsonschema:"enum=3,enum=4,title=NTP Version" jsonschema_description:"The NTP Version to use"` + MaximumDesync time.Duration `koanf:"max_desync" json:"max_desync" jsonschema:"default=3 seconds,title=Maximum Desync" jsonschema_description:"The maximum amount of time that the server can be out of sync"` + DisableStartupCheck bool `koanf:"disable_startup_check" json:"disable_startup_check" jsonschema:"default=false,title=Disable Startup Check" jsonschema_description:"Disables the NTP Startup Check entirely"` + DisableFailure bool `koanf:"disable_failure" json:"disable_failure" jsonschema:"default=false,title=Disable Failure" jsonschema_description:"Disables complete failure whe the Startup Check fails and instead just logs the error"` } // DefaultNTPConfiguration represents default configuration parameters for the NTP server. -var DefaultNTPConfiguration = NTPConfiguration{ +var DefaultNTPConfiguration = NTP{ Address: &AddressUDP{Address{valid: true, socket: false, port: 123, url: &url.URL{Scheme: AddressSchemeUDP, Host: "time.cloudflare.com:123"}}}, Version: 4, MaximumDesync: time.Second * 3, diff --git a/internal/configuration/schema/password_policy.go b/internal/configuration/schema/password_policy.go index 303618fa9..8ee389573 100644 --- a/internal/configuration/schema/password_policy.go +++ b/internal/configuration/schema/password_policy.go @@ -1,37 +1,35 @@ package schema -// PasswordPolicyStandardParams represents the configuration related to standard parameters of password policy. -type PasswordPolicyStandardParams struct { - Enabled bool `koanf:"enabled"` - MinLength int `koanf:"min_length"` - MaxLength int `koanf:"max_length"` - RequireUppercase bool `koanf:"require_uppercase"` - RequireLowercase bool `koanf:"require_lowercase"` - RequireNumber bool `koanf:"require_number"` - RequireSpecial bool `koanf:"require_special"` +// PasswordPolicy represents the configuration related to password policy. +type PasswordPolicy struct { + Standard PasswordPolicyStandard `koanf:"standard" json:"standard" jsonschema:"title=Standard" jsonschema_description:"The standard password policy engine"` + ZXCVBN PasswordPolicyZXCVBN `koanf:"zxcvbn" json:"zxcvbn" jsonschema:"title=ZXCVBN" jsonschema_description:"The ZXCVBN password policy engine"` } -// PasswordPolicyZXCVBNParams represents the configuration related to ZXCVBN parameters of password policy. -type PasswordPolicyZXCVBNParams struct { - Enabled bool `koanf:"enabled"` - MinScore int `koanf:"min_score"` +// PasswordPolicyStandard represents the configuration related to standard parameters of password policy. +type PasswordPolicyStandard struct { + Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the standard password policy engine"` + MinLength int `koanf:"min_length" json:"min_length" jsonschema:"title=Minimum Length" jsonschema_description:"Minimum password length"` + MaxLength int `koanf:"max_length" json:"max_length" jsonschema:"default=8,title=Maximum Length" jsonschema_description:"Maximum password length"` + RequireUppercase bool `koanf:"require_uppercase" json:"require_uppercase" jsonschema:"default=false,title=Require Uppercase" jsonschema_description:"Require uppercase characters"` + RequireLowercase bool `koanf:"require_lowercase" json:"require_lowercase" jsonschema:"default=false,title=Require Lowercase" jsonschema_description:"Require lowercase characters"` + RequireNumber bool `koanf:"require_number" json:"require_number" jsonschema:"default=false,title=Require Number" jsonschema_description:"Require numeric characters"` + RequireSpecial bool `koanf:"require_special" json:"require_special" jsonschema:"default=false,title=Require Special" jsonschema_description:"Require symbolic characters"` } -// PasswordPolicyConfiguration represents the configuration related to password policy. -type PasswordPolicyConfiguration struct { - Standard PasswordPolicyStandardParams `koanf:"standard"` - ZXCVBN PasswordPolicyZXCVBNParams `koanf:"zxcvbn"` +// PasswordPolicyZXCVBN represents the configuration related to ZXCVBN parameters of password policy. +type PasswordPolicyZXCVBN struct { + Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the ZXCVBN password policy engine"` + MinScore int `koanf:"min_score" json:"min_score" jsonschema:"default=3,title=Minimum Score" jsonschema_description:"The minimum ZXCVBN score allowed"` } // DefaultPasswordPolicyConfiguration is the default password policy configuration. -var DefaultPasswordPolicyConfiguration = PasswordPolicyConfiguration{ - Standard: PasswordPolicyStandardParams{ - Enabled: false, +var DefaultPasswordPolicyConfiguration = PasswordPolicy{ + Standard: PasswordPolicyStandard{ MinLength: 8, MaxLength: 0, }, - ZXCVBN: PasswordPolicyZXCVBNParams{ - Enabled: false, + ZXCVBN: PasswordPolicyZXCVBN{ MinScore: 3, }, } diff --git a/internal/configuration/schema/privacy_policy.go b/internal/configuration/schema/privacy_policy.go index 500f6c0cb..00d704ab0 100644 --- a/internal/configuration/schema/privacy_policy.go +++ b/internal/configuration/schema/privacy_policy.go @@ -6,7 +6,7 @@ import ( // PrivacyPolicy is the privacy policy configuration. type PrivacyPolicy struct { - Enabled bool `koanf:"enabled"` - RequireUserAcceptance bool `koanf:"require_user_acceptance"` - PolicyURL *url.URL `koanf:"policy_url"` + Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the Privacy Policy functionality"` + RequireUserAcceptance bool `koanf:"require_user_acceptance" json:"require_user_acceptance" jsonschema:"default=false,title=Require User Acceptance" jsonschema_description:"Enables the requirement for users to accept the policy"` + PolicyURL *url.URL `koanf:"policy_url" json:"policy_url" jsonschema:"title=Policy URL" jsonschema_description:"The URL of the privacy policy"` } diff --git a/internal/configuration/schema/regulation.go b/internal/configuration/schema/regulation.go index a5cf517e6..de79a3dad 100644 --- a/internal/configuration/schema/regulation.go +++ b/internal/configuration/schema/regulation.go @@ -4,15 +4,15 @@ import ( "time" ) -// RegulationConfiguration represents the configuration related to regulation. -type RegulationConfiguration struct { - MaxRetries int `koanf:"max_retries"` - FindTime time.Duration `koanf:"find_time,weak"` - BanTime time.Duration `koanf:"ban_time,weak"` +// Regulation represents the configuration related to regulation. +type Regulation struct { + MaxRetries int `koanf:"max_retries" json:"max_retries" jsonschema:"default=3,title=Maximum Retries" jsonschema_description:"The maximum number of failed attempts permitted before banning a user"` + FindTime time.Duration `koanf:"find_time" json:"find_time" jsonschema:"default=2 minutes,title=Find Time" jsonschema_description:"The amount of time to consider when determining the number of failed attempts"` + BanTime time.Duration `koanf:"ban_time" json:"ban_time" jsonschema:"default=5 minutes,title=Ban Time" jsonschema_description:"The amount of time to ban the user for when it's determined the maximum retries has been exceeded'"` } // DefaultRegulationConfiguration represents default configuration parameters for the regulator. -var DefaultRegulationConfiguration = RegulationConfiguration{ +var DefaultRegulationConfiguration = Regulation{ MaxRetries: 3, FindTime: time.Minute * 2, BanTime: time.Minute * 5, diff --git a/internal/configuration/schema/server.go b/internal/configuration/schema/server.go index bca2a0b9d..2f463fb2f 100644 --- a/internal/configuration/schema/server.go +++ b/internal/configuration/schema/server.go @@ -5,63 +5,63 @@ import ( "time" ) -// ServerConfiguration represents the configuration of the http server. -type ServerConfiguration struct { - Address *AddressTCP `koanf:"address"` - AssetPath string `koanf:"asset_path"` - DisableHealthcheck bool `koanf:"disable_healthcheck"` +// Server represents the configuration of the http server. +type Server struct { + Address *AddressTCP `koanf:"address" json:"address" jsonschema:"default=tcp://:9091/,title=Address" jsonschema_description:"The address to listen on"` + AssetPath string `koanf:"asset_path" json:"asset_path" jsonschema:"title=Asset Path" jsonschema_description:"The directory where the server asset overrides reside"` + DisableHealthcheck bool `koanf:"disable_healthcheck" json:"disable_healthcheck" jsonschema:"default=false,title=Disable Healthcheck" jsonschema_description:"Disables the healthcheck functionality"` - TLS ServerTLS `koanf:"tls"` - Headers ServerHeaders `koanf:"headers"` - Endpoints ServerEndpoints `koanf:"endpoints"` + TLS ServerTLS `koanf:"tls" json:"tls" jsonschema:"title=TLS" jsonschema_description:"The server TLS configuration"` + Headers ServerHeaders `koanf:"headers" json:"headers" jsonschema:"title=Headers" jsonschema_description:"The server headers configuration"` + Endpoints ServerEndpoints `koanf:"endpoints" json:"endpoints" jsonschema:"title=Endpoints" jsonschema_description:"The server endpoints configuration"` - Buffers ServerBuffers `koanf:"buffers"` - Timeouts ServerTimeouts `koanf:"timeouts"` + Buffers ServerBuffers `koanf:"buffers" json:"buffers" jsonschema:"title=Buffers" jsonschema_description:"The server buffers configuration"` + Timeouts ServerTimeouts `koanf:"timeouts" json:"timeouts" jsonschema:"title=Timeouts" jsonschema_description:"The server timeouts configuration"` // Deprecated: use address instead. - Host string `koanf:"host"` + Host string `koanf:"host" json:"host" jsonschema:"deprecated"` // Deprecated: use address instead. - Port int `koanf:"port"` + Port int `koanf:"port" json:"port" jsonschema:"deprecated"` // Deprecated: use address instead. - Path string `koanf:"path"` + Path string `koanf:"path" json:"path" jsonschema:"deprecated"` } // ServerEndpoints is the endpoints configuration for the HTTP server. type ServerEndpoints struct { - EnablePprof bool `koanf:"enable_pprof"` - EnableExpvars bool `koanf:"enable_expvars"` + EnablePprof bool `koanf:"enable_pprof" json:"enable_pprof" jsonschema:"default=false,title=Enable PProf" jsonschema_description:"Enables the developer specific pprof endpoints which should not be used in production and only used for debugging purposes"` + EnableExpvars bool `koanf:"enable_expvars" json:"enable_expvars" jsonschema:"default=false,title=Enable ExpVars" jsonschema_description:"Enables the developer specific ExpVars endpoints which should not be used in production and only used for debugging purposes"` - Authz map[string]ServerAuthzEndpoint `koanf:"authz"` + Authz map[string]ServerEndpointsAuthz `koanf:"authz" json:"authz" jsonschema:"title=Authz" jsonschema_description:"Configures the Authorization endpoints"` } -// ServerAuthzEndpoint is the Authz endpoints configuration for the HTTP server. -type ServerAuthzEndpoint struct { - Implementation string `koanf:"implementation"` +// ServerEndpointsAuthz is the Authz endpoints configuration for the HTTP server. +type ServerEndpointsAuthz struct { + Implementation string `koanf:"implementation" json:"implementation" jsonschema:"enum=ForwardAuth,enum=AuthRequest,enum=ExtAuthz,enum=Legacy,title=Implementation" jsonschema_description:"The specific Authorization implementation to use for this endpoint"` - AuthnStrategies []ServerAuthzEndpointAuthnStrategy `koanf:"authn_strategies"` + AuthnStrategies []ServerEndpointsAuthzAuthnStrategy `koanf:"authn_strategies" json:"authn_strategies" jsonschema:"title=Authn Strategies" jsonschema_description:"The specific Authorization strategies to use for this endpoint"` } -// ServerAuthzEndpointAuthnStrategy is the Authz endpoints configuration for the HTTP server. -type ServerAuthzEndpointAuthnStrategy struct { - Name string `koanf:"name"` +// ServerEndpointsAuthzAuthnStrategy is the Authz endpoints configuration for the HTTP server. +type ServerEndpointsAuthzAuthnStrategy struct { + Name string `koanf:"name" json:"name" jsonschema:"enum=HeaderAuthorization,enum=HeaderProxyAuthorization,enum=HeaderAuthRequestProxyAuthorization,enum=HeaderLegacy,enum=CookieSession,title=Name" jsonschema_description:"The name of the Authorization strategy to use"` } // ServerTLS represents the configuration of the http servers TLS options. type ServerTLS struct { - Certificate string `koanf:"certificate"` - Key string `koanf:"key"` - ClientCertificates []string `koanf:"client_certificates"` + Certificate string `koanf:"certificate" json:"certificate" jsonschema:"title=Certificate" jsonschema_description:"Path to the Certificate"` + Key string `koanf:"key" json:"key" jsonschema:"title=Key" jsonschema_description:"Path to the Private Key"` + ClientCertificates []string `koanf:"client_certificates" json:"client_certificates" jsonschema:"uniqueItems,title=Client Certificates" jsonschema_description:"Path to the Client Certificates to trust for mTLS"` } // ServerHeaders represents the customization of the http server headers. type ServerHeaders struct { - CSPTemplate string `koanf:"csp_template"` + CSPTemplate CSPTemplate `koanf:"csp_template" json:"csp_template" jsonschema:"title=CSP Template" jsonschema_description:"The Content Security Policy template"` } -// DefaultServerConfiguration represents the default values of the ServerConfiguration. -var DefaultServerConfiguration = ServerConfiguration{ +// DefaultServerConfiguration represents the default values of the Server. +var DefaultServerConfiguration = Server{ Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091", Path: "/"}}}, Buffers: ServerBuffers{ Read: 4096, @@ -73,13 +73,13 @@ var DefaultServerConfiguration = ServerConfiguration{ Idle: time.Second * 30, }, Endpoints: ServerEndpoints{ - Authz: map[string]ServerAuthzEndpoint{ + Authz: map[string]ServerEndpointsAuthz{ "legacy": { Implementation: "Legacy", }, "auth-request": { Implementation: "AuthRequest", - AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ + AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{ { Name: "HeaderAuthRequestProxyAuthorization", }, @@ -90,7 +90,7 @@ var DefaultServerConfiguration = ServerConfiguration{ }, "forward-auth": { Implementation: "ForwardAuth", - AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ + AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{ { Name: "HeaderProxyAuthorization", }, @@ -101,7 +101,7 @@ var DefaultServerConfiguration = ServerConfiguration{ }, "ext-authz": { Implementation: "ExtAuthz", - AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ + AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{ { Name: "HeaderProxyAuthorization", }, diff --git a/internal/configuration/schema/session.go b/internal/configuration/schema/session.go index 66719e202..7a53e8e35 100644 --- a/internal/configuration/schema/session.go +++ b/internal/configuration/schema/session.go @@ -6,67 +6,72 @@ import ( "time" ) -// RedisNode Represents a Node. -type RedisNode struct { - Host string `koanf:"host"` - Port int `koanf:"port"` +// Session represents the configuration related to user sessions. +type Session struct { + SessionCookieCommon `koanf:",squash"` + + Secret string `koanf:"secret" json:"secret" jsonschema:"title=Secret" jsonschema_description:"Secret used to encrypt the session data"` + + Cookies []SessionCookie `koanf:"cookies" json:"cookies" jsonschema:"title=Cookies" jsonschema_description:"List of cookie domain configurations"` + + Redis *SessionRedis `koanf:"redis" json:"redis" jsonschema:"title=Redis" jsonschema_description:"Redis Session Provider configuration"` + + // Deprecated: Use the cookies options instead. + Domain string `koanf:"domain" json:"domain" jsonschema:"deprecated"` } -// RedisHighAvailabilityConfiguration holds configuration variables for Redis Cluster/Sentinel. -type RedisHighAvailabilityConfiguration struct { - SentinelName string `koanf:"sentinel_name"` - SentinelUsername string `koanf:"sentinel_username"` - SentinelPassword string `koanf:"sentinel_password"` - Nodes []RedisNode `koanf:"nodes"` - RouteByLatency bool `koanf:"route_by_latency"` - RouteRandomly bool `koanf:"route_randomly"` -} - -// RedisSessionConfiguration represents the configuration related to redis session store. -type RedisSessionConfiguration struct { - Host string `koanf:"host"` - Port int `koanf:"port"` - Username string `koanf:"username"` - Password string `koanf:"password"` - DatabaseIndex int `koanf:"database_index"` - MaximumActiveConnections int `koanf:"maximum_active_connections"` - MinimumIdleConnections int `koanf:"minimum_idle_connections"` - TLS *TLSConfig `koanf:"tls"` - HighAvailability *RedisHighAvailabilityConfiguration `koanf:"high_availability"` -} - -// SessionConfiguration represents the configuration related to user sessions. -type SessionConfiguration struct { - Secret string `koanf:"secret"` - - SessionCookieCommonConfiguration `koanf:",squash"` - - Cookies []SessionCookieConfiguration `koanf:"cookies"` - - Redis *RedisSessionConfiguration `koanf:"redis"` -} - -type SessionCookieCommonConfiguration struct { - Name string `koanf:"name"` - Domain string `koanf:"domain"` - SameSite string `koanf:"same_site"` - Expiration time.Duration `koanf:"expiration"` - Inactivity time.Duration `koanf:"inactivity"` - RememberMe time.Duration `koanf:"remember_me"` +type SessionCookieCommon struct { + Name string `koanf:"name" json:"name" jsonschema:"default=authelia_session"` + SameSite string `koanf:"same_site" json:"same_site" jsonschema:"default=lax,enum=lax,enum=strict,enum=none"` + Expiration time.Duration `koanf:"expiration" json:"expiration" jsonschema:"default=1 hour"` + Inactivity time.Duration `koanf:"inactivity" json:"inactivity" jsonschema:"default=5 minutes"` + RememberMe time.Duration `koanf:"remember_me" json:"remember_me" jsonschema:"default=30 days"` DisableRememberMe bool } -// SessionCookieConfiguration represents the configuration for a cookie domain. -type SessionCookieConfiguration struct { - SessionCookieCommonConfiguration `koanf:",squash"` +// SessionCookie represents the configuration for a cookie domain. +type SessionCookie struct { + SessionCookieCommon `koanf:",squash"` - AutheliaURL *url.URL `koanf:"authelia_url"` + Domain string `koanf:"domain" json:"domain" jsonschema:"format=hostname,title=Domain" jsonschema_description:"The domain for this session cookie"` + AutheliaURL *url.URL `koanf:"authelia_url" json:"authelia_url" jsonschema:"format=uri,title=Authelia URL" jsonschema_description:"The Root Authelia URL to redirect users to for this session cookie"` +} + +// SessionRedis represents the configuration related to redis session store. +type SessionRedis struct { + Host string `koanf:"host" json:"host" jsonschema:"title=Host" jsonschema_description:"The redis server host"` + Port int `koanf:"port" json:"port" jsonschema:"default=6379,title=Host" jsonschema_description:"The redis server port"` + Username string `koanf:"username" json:"username" jsonschema:"title=Username" jsonschema_description:"The redis username"` + Password string `koanf:"password" json:"password" jsonschema:"title=Password" jsonschema_description:"The redis password"` + DatabaseIndex int `koanf:"database_index" json:"database_index" jsonschema:"default=0,title=Database Index" jsonschema_description:"The redis database index"` + MaximumActiveConnections int `koanf:"maximum_active_connections" json:"maximum_active_connections" jsonschema:"default=8,title=Maximum Active Connections" jsonschema_description:"The maximum connections that can be made to redis at one time"` + MinimumIdleConnections int `koanf:"minimum_idle_connections" json:"minimum_idle_connections" jsonschema:"title=Minimum Idle Connections" jsonschema_description:"The minimum idle connections that should be open to redis"` + TLS *TLS `koanf:"tls" json:"tls"` + + HighAvailability *SessionRedisHighAvailability `koanf:"high_availability" json:"high_availability"` +} + +// SessionRedisHighAvailability holds configuration variables for Redis Cluster/Sentinel. +type SessionRedisHighAvailability struct { + SentinelName string `koanf:"sentinel_name" json:"sentinel_name" jsonschema:"title=Sentinel Name" jsonschema_description:"The name of the sentinel instance"` + SentinelUsername string `koanf:"sentinel_username" json:"sentinel_username" jsonschema:"title=Sentinel Username" jsonschema_description:"The username for the sentinel instance"` + SentinelPassword string `koanf:"sentinel_password" json:"sentinel_password" jsonschema:"title=Sentinel Username" jsonschema_description:"The username for the sentinel instance"` + RouteByLatency bool `koanf:"route_by_latency" json:"route_by_latency" jsonschema:"default=false,title=Route by Latency" jsonschema_description:"Uses the Route by Latency mode"` + RouteRandomly bool `koanf:"route_randomly" json:"route_randomly" jsonschema:"default=false,title=Route Randomly" jsonschema_description:"Uses the Route Randomly mode"` + + Nodes []SessionRedisHighAvailabilityNode `koanf:"nodes" json:"nodes" jsonschema:"title=Nodes" jsonschema_description:"The pre-populated list of nodes for the sentinel instance"` +} + +// SessionRedisHighAvailabilityNode Represents a Node. +type SessionRedisHighAvailabilityNode struct { + Host string `koanf:"host" json:"host" jsonschema:"title=Host" jsonschema_description:"The redis sentinel node host"` + Port int `koanf:"port" json:"port" jsonschema:"default=26379,title=Port" jsonschema_description:"The redis sentinel node port"` } // DefaultSessionConfiguration is the default session configuration. -var DefaultSessionConfiguration = SessionConfiguration{ - SessionCookieCommonConfiguration: SessionCookieCommonConfiguration{ +var DefaultSessionConfiguration = Session{ + SessionCookieCommon: SessionCookieCommon{ Name: "authelia_session", Expiration: time.Hour, Inactivity: time.Minute * 5, @@ -76,8 +81,18 @@ var DefaultSessionConfiguration = SessionConfiguration{ } // DefaultRedisConfiguration is the default redis configuration. -var DefaultRedisConfiguration = RedisSessionConfiguration{ - TLS: &TLSConfig{ +var DefaultRedisConfiguration = SessionRedis{ + Port: 6379, + MaximumActiveConnections: 8, + TLS: &TLS{ + MinimumVersion: TLSVersion{Value: tls.VersionTLS12}, + }, +} + +// DefaultRedisHighAvailabilityConfiguration is the default redis configuration. +var DefaultRedisHighAvailabilityConfiguration = SessionRedis{ + Port: 26379, + TLS: &TLS{ MinimumVersion: TLSVersion{Value: tls.VersionTLS12}, }, } diff --git a/internal/configuration/schema/shared.go b/internal/configuration/schema/shared.go index 84ae6260b..3a22bf949 100644 --- a/internal/configuration/schema/shared.go +++ b/internal/configuration/schema/shared.go @@ -4,42 +4,36 @@ import ( "time" ) -// TLSConfig is a representation of the TLS configuration. -type TLSConfig struct { - MinimumVersion TLSVersion `koanf:"minimum_version"` - MaximumVersion TLSVersion `koanf:"maximum_version"` +// TLS is a representation of the TLS configuration. +type TLS struct { + MinimumVersion TLSVersion `koanf:"minimum_version" json:"minimum_version" jsonschema:"default=TLS1.2,title=Minimum Version" jsonschema_description:"The minimum TLS version accepted"` + MaximumVersion TLSVersion `koanf:"maximum_version" json:"maximum_version" jsonschema:"default=TLS1.3,title=Maximum Version" jsonschema_description:"The maximum TLS version accepted"` - SkipVerify bool `koanf:"skip_verify"` - ServerName string `koanf:"server_name"` + SkipVerify bool `koanf:"skip_verify" json:"skip_verify" jsonschema:"default=false,title=Skip Verify" jsonschema_description:"Disable all verification of the TLS properties"` + ServerName string `koanf:"server_name" json:"server_name" jsonschema:"format=hostname,title=Server Name" jsonschema_description:"The expected server name to match the certificate against"` - PrivateKey CryptographicPrivateKey `koanf:"private_key"` - CertificateChain X509CertificateChain `koanf:"certificate_chain"` -} - -// TLSCertificateConfig is a representation of the TLS Certificate configuration. -type TLSCertificateConfig struct { - Key CryptographicPrivateKey `koanf:"key"` - CertificateChain X509CertificateChain `koanf:"certificate_chain"` + PrivateKey CryptographicPrivateKey `koanf:"private_key" json:"private_key" jsonschema:"title=Private Key" jsonschema_description:"The private key"` + CertificateChain X509CertificateChain `koanf:"certificate_chain" json:"certificate_chain" jsonschema:"title=Certificate Chain" jsonschema_description:"The certificate chain"` } // ServerTimeouts represents server timeout configurations. type ServerTimeouts struct { - Read time.Duration `koanf:"read"` - Write time.Duration `koanf:"write"` - Idle time.Duration `koanf:"idle"` + Read time.Duration `koanf:"read" json:"read" jsonschema:"default=6 seconds,title=Read" jsonschema_description:"The read timeout"` + Write time.Duration `koanf:"write" json:"write" jsonschema:"default=6 seconds,title=Write" jsonschema_description:"The write timeout"` + Idle time.Duration `koanf:"idle" json:"idle" jsonschema:"default=30 seconds,title=Idle" jsonschema_description:"The idle timeout"` } // ServerBuffers represents server buffer configurations. type ServerBuffers struct { - Read int `koanf:"read"` - Write int `koanf:"write"` + Read int `koanf:"read" json:"read" jsonschema:"default=4096,title=Read" jsonschema_description:"The read buffer size"` + Write int `koanf:"write" json:"write" jsonschema:"default=4096,title=Write" jsonschema_description:"The write buffer size"` } // JWK represents a JWK. type JWK struct { - KeyID string `koanf:"key_id"` - Use string `koanf:"use"` - Algorithm string `koanf:"algorithm"` - Key CryptographicKey `koanf:"key"` - CertificateChain X509CertificateChain `koanf:"certificate_chain"` + KeyID string `koanf:"key_id" json:"key_id" jsonschema:"maxLength=100,title=Key ID" jsonschema_description:"The ID of this JWK"` + Use string `koanf:"use" json:"use" jsonschema:"default=sig,enum=sig,title=Use" jsonschema_description:"The Use of this JWK"` + Algorithm string `koanf:"algorithm" json:"algorithm" jsonschema:"enum=HS256,enum=HS384,enum=HS512,enum=RS256,enum=RS384,enum=RS512,enum=ES256,enum=ES384,enum=ES512,enum=PS256,enum=PS384,enum=PS512,title=Algorithm" jsonschema_description:"The Algorithm of this JWK"` + Key CryptographicKey `koanf:"key" json:"key" jsonschema_description:"The Private/Public key material of this JWK in Base64 PEM format"` + CertificateChain X509CertificateChain `koanf:"certificate_chain" json:"certificate_chain" jsonschema:"title=Certificate Chain" jsonschema_description:"The optional associated certificate which matches the Key public key portion for this JWK"` } diff --git a/internal/configuration/schema/storage.go b/internal/configuration/schema/storage.go index 0d7b318ed..9862c957e 100644 --- a/internal/configuration/schema/storage.go +++ b/internal/configuration/schema/storage.go @@ -6,82 +6,83 @@ import ( "time" ) -// LocalStorageConfiguration represents the configuration when using local storage. -type LocalStorageConfiguration struct { - Path string `koanf:"path"` +// Storage represents the configuration of the storage backend. +type Storage struct { + Local *StorageLocal `koanf:"local" json:"local" jsonschema:"title=Local" jsonschema_description:"The Local SQLite3 Storage configuration settings"` + MySQL *StorageMySQL `koanf:"mysql" json:"mysql" jsonschema:"title=MySQL" jsonschema_description:"The MySQL/MariaDB Storage configuration settings"` + PostgreSQL *StoragePostgreSQL `koanf:"postgres" json:"postgres" jsonschema:"title=PostgreSQL" jsonschema_description:"The PostgreSQL Storage configuration settings"` + + EncryptionKey string `koanf:"encryption_key" json:"encryption_key" jsonschema:"title=Encryption Key" jsonschema_description:"The Storage Encryption Key used to secure security sensitive values in the storage engine"` } -// SQLStorageConfiguration represents the configuration of the SQL database. -type SQLStorageConfiguration struct { - Address *AddressTCP `koanf:"address"` - Database string `koanf:"database"` - Username string `koanf:"username"` - Password string `koanf:"password"` - Timeout time.Duration `koanf:"timeout"` +// StorageLocal represents the configuration when using local storage. +type StorageLocal struct { + Path string `koanf:"path" json:"path" jsonschema:"title=Path" jsonschema_description:"The Path for the SQLite3 database file"` +} + +// StorageSQL represents the configuration of the SQL database. +type StorageSQL struct { + Address *AddressTCP `koanf:"address" json:"address" jsonschema:"title=Address" jsonschema_description:"The address of the database"` + Database string `koanf:"database" json:"database" jsonschema:"title=Database" jsonschema_description:"The database name to use upon a successful connection"` + Username string `koanf:"username" json:"username" jsonschema:"title=Username" jsonschema_description:"The username to use to authenticate"` + Password string `koanf:"password" json:"password" jsonschema:"title=Password" jsonschema_description:"The password to use to authenticate"` + Timeout time.Duration `koanf:"timeout" json:"timeout" jsonschema:"default=5 seconds,title=Timeout" jsonschema_description:"The timeout for the database connection"` // Deprecated: use address instead. - Host string `koanf:"host"` + Host string `koanf:"host" json:"host" jsonschema:"deprecated"` // Deprecated: use address instead. - Port int `koanf:"port"` + Port int `koanf:"port" json:"port" jsonschema:"deprecated"` } -// MySQLStorageConfiguration represents the configuration of a MySQL database. -type MySQLStorageConfiguration struct { - SQLStorageConfiguration `koanf:",squash"` +// StorageMySQL represents the configuration of a MySQL database. +type StorageMySQL struct { + StorageSQL `koanf:",squash"` - TLS *TLSConfig `koanf:"tls"` + TLS *TLS `koanf:"tls" json:"tls"` } -// PostgreSQLStorageConfiguration represents the configuration of a PostgreSQL database. -type PostgreSQLStorageConfiguration struct { - SQLStorageConfiguration `koanf:",squash"` - Schema string `koanf:"schema"` +// StoragePostgreSQL represents the configuration of a PostgreSQL database. +type StoragePostgreSQL struct { + StorageSQL `koanf:",squash"` + Schema string `koanf:"schema" json:"schema" jsonschema:"default=public"` - TLS *TLSConfig `koanf:"tls"` + TLS *TLS `koanf:"tls" json:"tls"` - SSL *PostgreSQLSSLStorageConfiguration `koanf:"ssl"` + // Deprecated: Use the TLS configuration instead. + SSL *StoragePostgreSQLSSL `koanf:"ssl" json:"ssl" jsonschema:"deprecated"` } -// PostgreSQLSSLStorageConfiguration represents the SSL configuration of a PostgreSQL database. -type PostgreSQLSSLStorageConfiguration struct { - Mode string `koanf:"mode"` - RootCertificate string `koanf:"root_certificate"` - Certificate string `koanf:"certificate"` - Key string `koanf:"key"` -} - -// StorageConfiguration represents the configuration of the storage backend. -type StorageConfiguration struct { - Local *LocalStorageConfiguration `koanf:"local"` - MySQL *MySQLStorageConfiguration `koanf:"mysql"` - PostgreSQL *PostgreSQLStorageConfiguration `koanf:"postgres"` - - EncryptionKey string `koanf:"encryption_key"` +// StoragePostgreSQLSSL represents the SSL configuration of a PostgreSQL database. +type StoragePostgreSQLSSL struct { + Mode string `koanf:"mode" json:"mode" jsonschema:"deprecated"` + RootCertificate string `koanf:"root_certificate" json:"root_certificate" jsonschema:"deprecated"` + Certificate string `koanf:"certificate" json:"certificate" jsonschema:"deprecated"` + Key string `koanf:"key" json:"key"` } // DefaultSQLStorageConfiguration represents the default SQL configuration. -var DefaultSQLStorageConfiguration = SQLStorageConfiguration{ +var DefaultSQLStorageConfiguration = StorageSQL{ Timeout: 5 * time.Second, } // DefaultMySQLStorageConfiguration represents the default MySQL configuration. -var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{ - TLS: &TLSConfig{ +var DefaultMySQLStorageConfiguration = StorageMySQL{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, } // DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration. -var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: SQLStorageConfiguration{ +var DefaultPostgreSQLStorageConfiguration = StoragePostgreSQL{ + StorageSQL: StorageSQL{ Address: &AddressTCP{Address{true, false, -1, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}}, }, Schema: "public", - TLS: &TLSConfig{ + TLS: &TLS{ MinimumVersion: TLSVersion{tls.VersionTLS12}, }, - SSL: &PostgreSQLSSLStorageConfiguration{ + SSL: &StoragePostgreSQLSSL{ Mode: "disable", }, } diff --git a/internal/configuration/schema/telemetry.go b/internal/configuration/schema/telemetry.go index 06160c252..60a08b2c4 100644 --- a/internal/configuration/schema/telemetry.go +++ b/internal/configuration/schema/telemetry.go @@ -5,22 +5,23 @@ import ( "time" ) -// TelemetryConfig represents the telemetry config. -type TelemetryConfig struct { - Metrics TelemetryMetricsConfig `koanf:"metrics"` +// Telemetry represents the telemetry config. +type Telemetry struct { + Metrics TelemetryMetrics `koanf:"metrics" json:"metrics" jsonschema:"title=Metrics" jsonschema_description:"The telemetry metrics server configuration"` } -// TelemetryMetricsConfig represents the telemetry metrics config. -type TelemetryMetricsConfig struct { - Enabled bool `koanf:"enabled"` - Address *AddressTCP `koanf:"address"` - Buffers ServerBuffers `koanf:"buffers"` - Timeouts ServerTimeouts `koanf:"timeouts"` +// TelemetryMetrics represents the telemetry metrics config. +type TelemetryMetrics struct { + Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the metrics server"` + Address *AddressTCP `koanf:"address" json:"address" jsonschema:"default=tcp://:9959/,title=Address" jsonschema_description:"The address for the metrics server to listen on"` + + Buffers ServerBuffers `koanf:"buffers" json:"buffers" jsonschema:"title=Buffers" jsonschema_description:"The server buffers configuration for the metrics server"` + Timeouts ServerTimeouts `koanf:"timeouts" json:"timeouts" jsonschema:"title=Timeouts" jsonschema_description:"The server timeouts configuration for the metrics server"` } // DefaultTelemetryConfig is the default telemetry configuration. -var DefaultTelemetryConfig = TelemetryConfig{ - Metrics: TelemetryMetricsConfig{ +var DefaultTelemetryConfig = Telemetry{ + Metrics: TelemetryMetrics{ Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959", Path: "/metrics"}}}, Buffers: ServerBuffers{ Read: 4096, diff --git a/internal/configuration/schema/totp.go b/internal/configuration/schema/totp.go index c6efbfed5..3f476524c 100644 --- a/internal/configuration/schema/totp.go +++ b/internal/configuration/schema/totp.go @@ -1,20 +1,20 @@ package schema -// TOTPConfiguration represents the configuration related to TOTP options. -type TOTPConfiguration struct { - Disable bool `koanf:"disable"` - Issuer string `koanf:"issuer"` - Algorithm string `koanf:"algorithm"` - Digits uint `koanf:"digits"` - Period uint `koanf:"period"` - Skew *uint `koanf:"skew"` - SecretSize uint `koanf:"secret_size"` +// TOTP represents the configuration related to TOTP options. +type TOTP struct { + Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the TOTP 2FA functionality"` + Issuer string `koanf:"issuer" json:"issuer" jsonschema:"default=Authelia,title=Issuer" jsonschema_description:"The issuer value for generated TOTP keys"` + Algorithm string `koanf:"algorithm" json:"algorithm" jsonschema:"default=SHA1,enum=SHA1,enum=SHA256,enum=SHA512,title=Algorithm" jsonschema_description:"The algorithm value for generated TOTP keys"` + Digits uint `koanf:"digits" json:"digits" jsonschema:"default=6,enum=6,enum=8,title=Digits" jsonschema_description:"The digits value for generated TOTP keys"` + Period uint `koanf:"period" json:"period" jsonschema:"default=30,title=Period" jsonschema_description:"The period value for generated TOTP keys"` + Skew *uint `koanf:"skew" json:"skew" jsonschema:"default=1,title=Skew" jsonschema_description:"The permitted skew for generated TOTP keys"` + SecretSize uint `koanf:"secret_size" json:"secret_size" jsonschema:"default=32,minimum=20,title=Secret Size" jsonschema_description:"The secret size for generated TOTP keys"` } var defaultOtpSkew = uint(1) // DefaultTOTPConfiguration represents default configuration parameters for TOTP generation. -var DefaultTOTPConfiguration = TOTPConfiguration{ +var DefaultTOTPConfiguration = TOTP{ Issuer: "Authelia", Algorithm: TOTPAlgorithmSHA1, Digits: 6, diff --git a/internal/configuration/schema/types.go b/internal/configuration/schema/types.go index 3e5c6ac65..5cfe22d98 100644 --- a/internal/configuration/schema/types.go +++ b/internal/configuration/schema/types.go @@ -10,18 +10,33 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "regexp" "strings" "time" + "github.com/authelia/jsonschema" "github.com/go-crypt/crypt" "github.com/go-crypt/crypt/algorithm" "github.com/go-crypt/crypt/algorithm/plaintext" + "github.com/valyala/fasthttp" + "gopkg.in/yaml.v3" ) var cdecoder algorithm.DecoderRegister // DecodePasswordDigest returns a new PasswordDigest if it can be decoded. func DecodePasswordDigest(encodedDigest string) (digest *PasswordDigest, err error) { + var d algorithm.Digest + + if d, err = DecodeAlgorithmDigest(encodedDigest); err != nil { + return nil, err + } + + return NewPasswordDigest(d), nil +} + +// DecodeAlgorithmDigest returns a new algorithm.Digest if it can be decoded. +func DecodeAlgorithmDigest(encodedDigest string) (digest algorithm.Digest, err error) { if cdecoder == nil { if cdecoder, err = crypt.NewDefaultDecoder(); err != nil { return nil, fmt.Errorf("failed to initialize decoder: %w", err) @@ -32,13 +47,12 @@ func DecodePasswordDigest(encodedDigest string) (digest *PasswordDigest, err err } } - var d algorithm.Digest + return cdecoder.Decode(encodedDigest) +} - if d, err = cdecoder.Decode(encodedDigest); err != nil { - return nil, err - } - - return &PasswordDigest{Digest: d}, nil +// NewPasswordDigest returns a new *PasswordDigest from an algorithm.Digest. +func NewPasswordDigest(digest algorithm.Digest) *PasswordDigest { + return &PasswordDigest{Digest: digest} } // PasswordDigest is a configuration type for the crypt.Digest. @@ -46,6 +60,14 @@ type PasswordDigest struct { algorithm.Digest } +// JSONSchema returns the JSON Schema information for the PasswordDigest type. +func (PasswordDigest) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Pattern: `^\$((argon2(id|i|d)\$v=19\$m=\d+,t=\d+,p=\d+|scrypt\$ln=\d+,r=\d+,p=\d+)\$[a-zA-Z0-9\/+]+\$[a-zA-Z0-9\/+]+|pbkdf2(-sha(224|256|384|512))?\$\d+\$[a-zA-Z0-9\/.]+\$[a-zA-Z0-9\/.]+|bcrypt-sha256\$v=2,t=2b,r=\d+\$[a-zA-Z0-9\/.]+\$[a-zA-Z0-9\/.]+|2(a|b|y)?\$\d+\$[a-zA-Z0-9.\/]+|(5|6)\$rounds=\d+\$[a-zA-Z0-9.\/]+\$[a-zA-Z0-9.\/]+|plaintext\$.+|base64\$[a-zA-Z0-9.=\/]+)$`, + } +} + // IsPlainText returns true if the underlying algorithm.Digest is a *plaintext.Digest. func (d *PasswordDigest) IsPlainText() bool { if d == nil || d.Digest == nil { @@ -60,6 +82,20 @@ func (d *PasswordDigest) IsPlainText() bool { } } +func (d *PasswordDigest) UnmarshalYAML(value *yaml.Node) (err error) { + digestRaw := "" + + if err = value.Decode(&digestRaw); err != nil { + return err + } + + if d.Digest, err = DecodeAlgorithmDigest(digestRaw); err != nil { + return err + } + + return nil +} + // NewX509CertificateChain creates a new *X509CertificateChain from a given string, parsing each PEM block one by one. func NewX509CertificateChain(in string) (chain *X509CertificateChain, err error) { if in == "" { @@ -130,6 +166,19 @@ type TLSVersion struct { Value uint16 } +// JSONSchema returns the JSON Schema information for the TLSVersion type. +func (TLSVersion) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Enum: []any{ + "TLS1.0", + "TLS1.1", + "TLS1.2", + "TLS1.3", + }, + } +} + // MaxVersion returns the value of this as a MaxVersion value. func (v *TLSVersion) MaxVersion() uint16 { if v.Value == 0 { @@ -180,6 +229,14 @@ type X509CertificateChain struct { certs []*x509.Certificate } +// JSONSchema returns the JSON Schema information for the X509CertificateChain type. +func (X509CertificateChain) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Pattern: `^(-{5}BEGIN CERTIFICATE-{5}\n([a-zA-Z0-9/+]{1,64}\n)+([a-zA-Z0-9/+]{1,64}[=]{0,2})\n-{5}END CERTIFICATE-{5}\n?)+$`, + } +} + // Thumbprint returns the Thumbprint for the first certificate. func (c *X509CertificateChain) Thumbprint(hash crypto.Hash) []byte { if len(c.certs) == 0 { @@ -330,3 +387,160 @@ func (c *X509CertificateChain) Validate() (err error) { return nil } + +type AccessControlRuleNetworks []string + +func (AccessControlRuleNetworks) JSONSchema() *jsonschema.Schema { + return &jsonschemaWeakStringUniqueSlice +} + +type IdentityProvidersOpenIDConnectClientRedirectURIs []string + +func (IdentityProvidersOpenIDConnectClientRedirectURIs) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + &jsonschemaURI, + { + Type: "array", + Items: &jsonschemaURI, + UniqueItems: true, + }, + }, + } +} + +// AccessControlNetworkNetworks represents the ACL AccessControlNetworkNetworks type. +type AccessControlNetworkNetworks []string + +func (AccessControlNetworkNetworks) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + &jsonschemaACLNetwork, + { + Type: "array", + Items: &jsonschemaACLNetwork, + UniqueItems: true, + }, + }, + } +} + +type AccessControlRuleDomains []string + +func (AccessControlRuleDomains) JSONSchema() *jsonschema.Schema { + return &jsonschemaWeakStringUniqueSlice +} + +type AccessControlRuleMethods []string + +func (AccessControlRuleMethods) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + &jsonschemaACLMethod, + { + Type: "array", + Items: &jsonschemaACLMethod, + UniqueItems: true, + }, + }, + } +} + +// AccessControlRuleRegex represents the ACL AccessControlRuleSubjects type. +type AccessControlRuleRegex []regexp.Regexp + +func (AccessControlRuleRegex) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + { + Type: "string", + Format: "regex", + }, + { + Type: "array", + Items: &jsonschema.Schema{ + Type: "string", + Format: "regex", + }, + UniqueItems: true, + }, + }, + } +} + +// AccessControlRuleSubjects represents the ACL AccessControlRuleSubjects type. +type AccessControlRuleSubjects [][]string + +func (AccessControlRuleSubjects) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + &jsonschemaACLSubject, + { + Type: "array", + Items: &jsonschemaACLSubject, + }, + { + Type: "array", + Items: &jsonschema.Schema{ + Type: "array", + Items: &jsonschemaACLSubject, + }, + UniqueItems: true, + }, + }, + } +} + +type CSPTemplate string + +var jsonschemaURI = jsonschema.Schema{ + Type: "string", + Format: "uri", +} + +var jsonschemaWeakStringUniqueSlice = jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + { + Type: "string", + }, + { + Type: "array", + Items: &jsonschema.Schema{ + Type: "string", + }, + UniqueItems: true, + }, + }, +} + +var jsonschemaACLNetwork = jsonschema.Schema{ + Type: "string", + Pattern: `((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/([0-2]?[0-9]|3[0-2]))?$)|(^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))?(\/(12[0-8]|1[0-1][0-9]|[0-9]{1,2}))?$))`, +} + +var jsonschemaACLSubject = jsonschema.Schema{ + Type: "string", + Pattern: "^(user|group):.+$", +} + +var jsonschemaACLMethod = jsonschema.Schema{ + Type: "string", + Enum: []any{ + fasthttp.MethodGet, + fasthttp.MethodHead, + fasthttp.MethodPost, + fasthttp.MethodPut, + fasthttp.MethodPatch, + fasthttp.MethodDelete, + fasthttp.MethodTrace, + fasthttp.MethodConnect, + fasthttp.MethodOptions, + "COPY", + "LOCK", + "MKCOL", + "MOVE", + "PROPFIND", + "PROPPATCH", + "UNLOCK", + }, +} diff --git a/internal/configuration/schema/types_address.go b/internal/configuration/schema/types_address.go index 95005de38..c736cad9b 100644 --- a/internal/configuration/schema/types_address.go +++ b/internal/configuration/schema/types_address.go @@ -6,6 +6,8 @@ import ( "net/url" "strconv" "strings" + + "github.com/authelia/jsonschema" ) // NewAddress returns an *Address and error depending on the ability to parse the string as an Address. @@ -129,21 +131,53 @@ type AddressTCP struct { Address } +func (AddressTCP) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Format: "uri", + Pattern: `^((tcp(4|6)?:\/\/)?([^:\/]*(:\d+)|[^:\/]+(:\d+)?)(\/.*)?|unix:\/\/\/[^?\n]+(\?umask=[0-7]{3,4})?)$`, + } +} + // AddressUDP is just a type with an underlying type of Address. type AddressUDP struct { Address } +func (AddressUDP) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Format: "uri", + Pattern: `^(udp(4|6)?:\/\/)?([^:\/]*(:\d+)|[^:\/]+(:\d+)?)(\/.*)?$`, + } +} + // AddressLDAP is just a type with an underlying type of Address. type AddressLDAP struct { Address } +func (AddressLDAP) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Format: "uri", + Pattern: `^((ldaps?:\/\/)?([^:\/]*(:\d+)|[^:\/]+(:\d+)?)?|ldapi:\/\/(\/[^?\n]+)?)$`, + } +} + // AddressSMTP is just a type with an underlying type of Address. type AddressSMTP struct { Address } +func (AddressSMTP) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Format: "uri", + Pattern: `^((smtp|submissions?):\/\/)?([^:\/]*(:\d+)|[^:\/]+(:\d+)?)?$`, + } +} + // Address represents an address. type Address struct { valid bool @@ -154,6 +188,15 @@ type Address struct { url *url.URL } +// JSONSchema returns the appropriate jsonsch ema for this type. +func (Address) JSONSchema() *jsonschema.Schema { + return &jsonschema.Schema{ + Type: "string", + Format: "uri", + Pattern: `^((unix:\/\/)?\/[^?\n]+(\?umask=[0-7]{3,4})?|ldapi:\/\/(\/[^?\n]+)?|(((tcp|udp)(4|6)?|ldaps?|smtp|submissions?):\/\/)?[^:\/]*(:\d+)?(\/.*)?)$`, + } +} + // Valid returns true if the Address is valid. func (a *Address) Valid() bool { return a.valid diff --git a/internal/configuration/schema/webauthn.go b/internal/configuration/schema/webauthn.go index a544225c5..c4c97cc9c 100644 --- a/internal/configuration/schema/webauthn.go +++ b/internal/configuration/schema/webauthn.go @@ -6,19 +6,19 @@ import ( "github.com/go-webauthn/webauthn/protocol" ) -// WebAuthnConfiguration represents the webauthn config. -type WebAuthnConfiguration struct { - Disable bool `koanf:"disable"` - DisplayName string `koanf:"display_name"` +// WebAuthn represents the webauthn config. +type WebAuthn struct { + Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the WebAuthn 2FA functionality"` + DisplayName string `koanf:"display_name" json:"display_name" jsonschema:"default=Authelia,title=Display Name" jsonschema_description:"The display name attribute for the WebAuthn relying party"` - ConveyancePreference protocol.ConveyancePreference `koanf:"attestation_conveyance_preference"` - UserVerification protocol.UserVerificationRequirement `koanf:"user_verification"` + ConveyancePreference protocol.ConveyancePreference `koanf:"attestation_conveyance_preference" json:"attestation_conveyance_preference" jsonschema:"default=indirect,enum=none,enum=indirect,enum=direct,title=Conveyance Preference" jsonschema_description:"The default conveyance preference for all WebAuthn credentials"` + UserVerification protocol.UserVerificationRequirement `koanf:"user_verification" json:"user_verification" jsonschema:"default=preferred,enum=discouraged,enum=preferred,enum=required,title=User Verification" jsonschema_description:"The default user verification preference for all WebAuthn credentials"` - Timeout time.Duration `koanf:"timeout"` + Timeout time.Duration `koanf:"timeout" json:"timeout" jsonschema:"default=60 seconds,title=Timeout" jsonschema_description:"The default timeout for all WebAuthn ceremonies"` } -// DefaultWebAuthnConfiguration describes the default values for the WebAuthnConfiguration. -var DefaultWebAuthnConfiguration = WebAuthnConfiguration{ +// DefaultWebAuthnConfiguration describes the default values for the WebAuthn. +var DefaultWebAuthnConfiguration = WebAuthn{ DisplayName: "Authelia", Timeout: time.Second * 60, diff --git a/internal/configuration/validator/access_control.go b/internal/configuration/validator/access_control.go index 93f1efa4c..d9c817547 100644 --- a/internal/configuration/validator/access_control.go +++ b/internal/configuration/validator/access_control.go @@ -22,7 +22,7 @@ func IsSubjectValid(subject string) (isValid bool) { } // IsNetworkGroupValid check if a network group is valid. -func IsNetworkGroupValid(config schema.AccessControlConfiguration, network string) bool { +func IsNetworkGroupValid(config schema.AccessControl, network string) bool { for _, networks := range config.Networks { if network != networks.Name { continue @@ -44,7 +44,7 @@ func IsNetworkValid(network string) (isValid bool) { return true } -func ruleDescriptor(position int, rule schema.ACLRule) string { +func ruleDescriptor(position int, rule schema.AccessControlRule) string { if len(rule.Domains) == 0 { return fmt.Sprintf("#%d", position) } @@ -115,7 +115,7 @@ func ValidateRules(config *schema.Configuration, validator *schema.StructValidat } } -func validateBypass(rulePosition int, rule schema.ACLRule, validator *schema.StructValidator) { +func validateBypass(rulePosition int, rule schema.AccessControlRule, validator *schema.StructValidator) { if len(rule.Subjects) != 0 { validator.Push(fmt.Errorf(errAccessControlRuleBypassPolicyInvalidWithSubjects, ruleDescriptor(rulePosition, rule))) } @@ -128,7 +128,7 @@ func validateBypass(rulePosition int, rule schema.ACLRule, validator *schema.Str } } -func validateDomains(rulePosition int, rule schema.ACLRule, validator *schema.StructValidator) { +func validateDomains(rulePosition int, rule schema.AccessControlRule, validator *schema.StructValidator) { if len(rule.Domains)+len(rule.DomainsRegex) == 0 { validator.Push(fmt.Errorf(errFmtAccessControlRuleNoDomains, ruleDescriptor(rulePosition, rule))) } @@ -140,7 +140,7 @@ func validateDomains(rulePosition int, rule schema.ACLRule, validator *schema.St } } -func validateNetworks(rulePosition int, rule schema.ACLRule, config schema.AccessControlConfiguration, validator *schema.StructValidator) { +func validateNetworks(rulePosition int, rule schema.AccessControlRule, config schema.AccessControl, validator *schema.StructValidator) { for _, network := range rule.Networks { if !IsNetworkValid(network) { if !IsNetworkGroupValid(config, network) { @@ -150,7 +150,7 @@ func validateNetworks(rulePosition int, rule schema.ACLRule, config schema.Acces } } -func validateSubjects(rulePosition int, rule schema.ACLRule, validator *schema.StructValidator) { +func validateSubjects(rulePosition int, rule schema.AccessControlRule, validator *schema.StructValidator) { for _, subjectRule := range rule.Subjects { for _, subject := range subjectRule { if !IsSubjectValid(subject) { @@ -160,7 +160,7 @@ func validateSubjects(rulePosition int, rule schema.ACLRule, validator *schema.S } } -func validateMethods(rulePosition int, rule schema.ACLRule, validator *schema.StructValidator) { +func validateMethods(rulePosition int, rule schema.AccessControlRule, validator *schema.StructValidator) { invalid, duplicates := validateList(rule.Methods, validACLHTTPMethodVerbs, true) if len(invalid) != 0 { @@ -173,7 +173,7 @@ func validateMethods(rulePosition int, rule schema.ACLRule, validator *schema.St } //nolint:gocyclo -func validateQuery(i int, rule schema.ACLRule, config *schema.Configuration, validator *schema.StructValidator) { +func validateQuery(i int, rule schema.AccessControlRule, config *schema.Configuration, validator *schema.StructValidator) { for j := 0; j < len(config.AccessControl.Rules[i].Query); j++ { for k := 0; k < len(config.AccessControl.Rules[i].Query[j]); k++ { if config.AccessControl.Rules[i].Query[j][k].Operator == "" { diff --git a/internal/configuration/validator/access_control_test.go b/internal/configuration/validator/access_control_test.go index 4859909c3..f440393ba 100644 --- a/internal/configuration/validator/access_control_test.go +++ b/internal/configuration/validator/access_control_test.go @@ -21,7 +21,7 @@ type AccessControl struct { func (suite *AccessControl) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = &schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: policyDeny, Networks: schema.DefaultACLNetwork, @@ -40,7 +40,7 @@ func (suite *AccessControl) TestShouldValidateCompleteConfiguration() { func (suite *AccessControl) TestShouldValidateEitherDomainsOrDomainsRegex() { domainsRegex := regexp.MustCompile(`^abc.example.com$`) - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"abc.example.com"}, Policy: "bypass", @@ -74,7 +74,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidDefaultPolicy() { } func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() { - suite.config.AccessControl.Networks = []schema.ACLNetwork{ + suite.config.AccessControl.Networks = []schema.AccessControlNetwork{ { Name: "internal", Networks: []string{"abc.def.ghi.jkl"}, @@ -90,7 +90,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() { } func (suite *AccessControl) TestShouldRaiseWarningOnBadDomain() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"*example.com"}, Policy: "one_factor", @@ -106,7 +106,7 @@ func (suite *AccessControl) TestShouldRaiseWarningOnBadDomain() { } func (suite *AccessControl) TestShouldRaiseErrorWithNoRulesDefined() { - suite.config.AccessControl.Rules = []schema.ACLRule{} + suite.config.AccessControl.Rules = []schema.AccessControlRule{} ValidateRules(suite.config, suite.validator) @@ -117,7 +117,7 @@ func (suite *AccessControl) TestShouldRaiseErrorWithNoRulesDefined() { } func (suite *AccessControl) TestShouldRaiseWarningWithNoRulesDefined() { - suite.config.AccessControl.Rules = []schema.ACLRule{} + suite.config.AccessControl.Rules = []schema.AccessControlRule{} suite.config.AccessControl.DefaultPolicy = policyTwoFactor @@ -130,7 +130,7 @@ func (suite *AccessControl) TestShouldRaiseWarningWithNoRulesDefined() { } func (suite *AccessControl) TestShouldRaiseErrorsWithEmptyRules() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ {}, { Policy: "wrong", @@ -149,7 +149,7 @@ func (suite *AccessControl) TestShouldRaiseErrorsWithEmptyRules() { } func (suite *AccessControl) TestShouldRaiseErrorInvalidPolicy() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"public.example.com"}, Policy: testInvalid, @@ -165,7 +165,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidPolicy() { } func (suite *AccessControl) TestShouldRaiseErrorInvalidNetwork() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"public.example.com"}, Policy: "bypass", @@ -182,7 +182,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidNetwork() { } func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"public.example.com"}, Policy: "bypass", @@ -199,7 +199,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() { } func (suite *AccessControl) TestShouldRaiseErrorDuplicateMethod() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"public.example.com"}, Policy: "bypass", @@ -218,7 +218,7 @@ func (suite *AccessControl) TestShouldRaiseErrorDuplicateMethod() { func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() { domains := []string{"public.example.com"} subjects := [][]string{{testInvalid}} - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: domains, Policy: "bypass", @@ -236,7 +236,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() { } func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGroup() { - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { DomainsRegex: MustCompileRegexps([]string{`^(?P\w+)\.example\.com$`}), Policy: "bypass", @@ -253,11 +253,11 @@ func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGrou func (suite *AccessControl) TestShouldSetQueryDefaults() { domains := []string{"public.example.com"} - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "", Key: "example"}, }, @@ -269,7 +269,7 @@ func (suite *AccessControl) TestShouldSetQueryDefaults() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "pattern", Key: "a", Value: "^(x|y|z)$"}, }, @@ -296,11 +296,11 @@ func (suite *AccessControl) TestShouldSetQueryDefaults() { func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { domains := []string{"public.example.com"} - suite.config.AccessControl.Rules = []schema.ACLRule{ + suite.config.AccessControl.Rules = []schema.AccessControlRule{ { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "equal", Key: "example"}, }, @@ -309,7 +309,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "present"}, }, @@ -318,7 +318,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "present", Key: "a"}, }, @@ -327,7 +327,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "absent", Key: "a"}, }, @@ -336,7 +336,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {}, }, @@ -345,7 +345,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "not", Key: "a", Value: "a"}, }, @@ -354,7 +354,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "pattern", Key: "a", Value: "(bad pattern"}, }, @@ -363,7 +363,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "present", Key: "a", Value: "not good"}, }, @@ -372,7 +372,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { { Domains: domains, Policy: "bypass", - Query: [][]schema.ACLQueryRule{ + Query: [][]schema.AccessControlRuleQuery{ { {Operator: "present", Key: "a", Value: 5}, }, @@ -399,7 +399,7 @@ func TestAccessControl(t *testing.T) { } func TestShouldReturnCorrectResultsForValidNetworkGroups(t *testing.T) { - config := schema.AccessControlConfiguration{ + config := schema.AccessControl{ Networks: schema.DefaultACLNetwork, } diff --git a/internal/configuration/validator/authentication.go b/internal/configuration/validator/authentication.go index 4e7c5305f..8740e9e6d 100644 --- a/internal/configuration/validator/authentication.go +++ b/internal/configuration/validator/authentication.go @@ -52,7 +52,7 @@ func ValidateAuthenticationBackend(config *schema.AuthenticationBackend, validat } // validateFileAuthenticationBackend validates and updates the file authentication backend configuration. -func validateFileAuthenticationBackend(config *schema.FileAuthenticationBackend, validator *schema.StructValidator) { +func validateFileAuthenticationBackend(config *schema.AuthenticationBackendFile, validator *schema.StructValidator) { if config.Path == "" { validator.Push(fmt.Errorf(errFmtFileAuthBackendPathNotConfigured)) } @@ -61,7 +61,7 @@ func validateFileAuthenticationBackend(config *schema.FileAuthenticationBackend, } // ValidatePasswordConfiguration validates the file auth backend password configuration. -func ValidatePasswordConfiguration(config *schema.Password, validator *schema.StructValidator) { +func ValidatePasswordConfiguration(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { validateFileAuthenticationBackendPasswordConfigLegacy(config) switch { @@ -81,7 +81,7 @@ func ValidatePasswordConfiguration(config *schema.Password, validator *schema.St } //nolint:gocyclo // Function is well formed. -func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.Password, validator *schema.StructValidator) { +func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { switch { case config.Argon2.Variant == "": config.Argon2.Variant = schema.DefaultPasswordConfig.Argon2.Variant @@ -139,7 +139,7 @@ func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.Passwo } } -func validateFileAuthenticationBackendPasswordConfigSHA2Crypt(config *schema.Password, validator *schema.StructValidator) { +func validateFileAuthenticationBackendPasswordConfigSHA2Crypt(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { switch { case config.SHA2Crypt.Variant == "": config.SHA2Crypt.Variant = schema.DefaultPasswordConfig.SHA2Crypt.Variant @@ -168,7 +168,7 @@ func validateFileAuthenticationBackendPasswordConfigSHA2Crypt(config *schema.Pas } } -func validateFileAuthenticationBackendPasswordConfigPBKDF2(config *schema.Password, validator *schema.StructValidator) { +func validateFileAuthenticationBackendPasswordConfigPBKDF2(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { switch { case config.PBKDF2.Variant == "": config.PBKDF2.Variant = schema.DefaultPasswordConfig.PBKDF2.Variant @@ -197,7 +197,7 @@ func validateFileAuthenticationBackendPasswordConfigPBKDF2(config *schema.Passwo } } -func validateFileAuthenticationBackendPasswordConfigBCrypt(config *schema.Password, validator *schema.StructValidator) { +func validateFileAuthenticationBackendPasswordConfigBCrypt(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { switch { case config.BCrypt.Variant == "": config.BCrypt.Variant = schema.DefaultPasswordConfig.BCrypt.Variant @@ -218,7 +218,7 @@ func validateFileAuthenticationBackendPasswordConfigBCrypt(config *schema.Passwo } //nolint:gocyclo -func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.Password, validator *schema.StructValidator) { +func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) { switch { case config.SCrypt.Iterations == 0: config.SCrypt.Iterations = schema.DefaultPasswordConfig.SCrypt.Iterations @@ -265,8 +265,8 @@ func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.Passwo } } -//nolint:gocyclo // Function is clear enough. -func validateFileAuthenticationBackendPasswordConfigLegacy(config *schema.Password) { +//nolint:gocyclo,staticcheck // Function is clear enough and being used for deprecated functionality mapping. +func validateFileAuthenticationBackendPasswordConfigLegacy(config *schema.AuthenticationBackendFilePassword) { switch config.Algorithm { case hashLegacySHA512: config.Algorithm = hashSHA2Crypt @@ -325,7 +325,7 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val defaultTLS.ServerName = validateLDAPAuthenticationAddress(config.LDAP, validator) if config.LDAP.TLS == nil { - config.LDAP.TLS = &schema.TLSConfig{} + config.LDAP.TLS = &schema.TLS{} } if err := ValidateTLSConfig(config.LDAP.TLS, defaultTLS); err != nil { @@ -347,8 +347,8 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val validateLDAPRequiredParameters(config, validator) } -func validateLDAPAuthenticationBackendImplementation(config *schema.AuthenticationBackend, validator *schema.StructValidator) *schema.TLSConfig { - var implementation *schema.LDAPAuthenticationBackend +func validateLDAPAuthenticationBackendImplementation(config *schema.AuthenticationBackend, validator *schema.StructValidator) *schema.TLS { + var implementation *schema.AuthenticationBackendLDAP switch config.LDAP.Implementation { case schema.LDAPImplementationCustom: @@ -367,14 +367,14 @@ func validateLDAPAuthenticationBackendImplementation(config *schema.Authenticati validator.Push(fmt.Errorf(errFmtLDAPAuthBackendOptionMustBeOneOf, "implementation", strJoinOr(validLDAPImplementations), config.LDAP.Implementation)) } - tlsconfig := &schema.TLSConfig{} + tlsconfig := &schema.TLS{} if implementation != nil { if config.LDAP.Timeout == 0 { config.LDAP.Timeout = implementation.Timeout } - tlsconfig = &schema.TLSConfig{ + tlsconfig = &schema.TLS{ MinimumVersion: implementation.TLS.MinimumVersion, MaximumVersion: implementation.TLS.MaximumVersion, } @@ -389,7 +389,7 @@ func ldapImplementationShouldSetStr(config, implementation string) bool { return config == "" && implementation != "" } -func setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config *schema.LDAPAuthenticationBackend, implementation *schema.LDAPAuthenticationBackend) { +func setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config *schema.AuthenticationBackendLDAP, implementation *schema.AuthenticationBackendLDAP) { if ldapImplementationShouldSetStr(config.AdditionalUsersDN, implementation.AdditionalUsersDN) { config.AdditionalUsersDN = implementation.AdditionalUsersDN } @@ -435,7 +435,7 @@ func setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config * } } -func validateLDAPAuthenticationAddress(config *schema.LDAPAuthenticationBackend, validator *schema.StructValidator) (hostname string) { +func validateLDAPAuthenticationAddress(config *schema.AuthenticationBackendLDAP, validator *schema.StructValidator) (hostname string) { if config.Address == nil { validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "address")) diff --git a/internal/configuration/validator/authentication_test.go b/internal/configuration/validator/authentication_test.go index b329cef63..2817c8960 100644 --- a/internal/configuration/validator/authentication_test.go +++ b/internal/configuration/validator/authentication_test.go @@ -17,8 +17,8 @@ func TestShouldRaiseErrorWhenBothBackendsProvided(t *testing.T) { validator := schema.NewStructValidator() backendConfig := schema.AuthenticationBackend{} - backendConfig.LDAP = &schema.LDAPAuthenticationBackend{} - backendConfig.File = &schema.FileAuthenticationBackend{ + backendConfig.LDAP = &schema.AuthenticationBackendLDAP{} + backendConfig.File = &schema.AuthenticationBackendFile{ Path: "/tmp", } @@ -55,7 +55,7 @@ func (suite *FileBasedAuthenticationBackend) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.File = &schema.FileAuthenticationBackend{Path: "/a/path", Password: password} + suite.config.File = &schema.AuthenticationBackendFile{Path: "/a/path", Password: password} } func (suite *FileBasedAuthenticationBackend) TestShouldValidateCompleteConfiguration() { @@ -77,33 +77,33 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenNoPathProvi } func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultConfigurationWhenBlank() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} - suite.Equal(0, suite.config.File.Password.KeyLength) - suite.Equal(0, suite.config.File.Password.Iterations) - suite.Equal(0, suite.config.File.Password.SaltLength) suite.Equal("", suite.config.File.Password.Algorithm) - suite.Equal(0, suite.config.File.Password.Memory) - suite.Equal(0, suite.config.File.Password.Parallelism) + suite.Equal(0, suite.config.File.Password.KeyLength) //nolint:staticcheck + suite.Equal(0, suite.config.File.Password.Iterations) //nolint:staticcheck + suite.Equal(0, suite.config.File.Password.SaltLength) //nolint:staticcheck + suite.Equal(0, suite.config.File.Password.Memory) //nolint:staticcheck + suite.Equal(0, suite.config.File.Password.Parallelism) //nolint:staticcheck ValidateAuthenticationBackend(&suite.config, suite.validator) suite.Len(suite.validator.Warnings(), 0) suite.Len(suite.validator.Errors(), 0) - suite.Equal(schema.DefaultPasswordConfig.KeyLength, suite.config.File.Password.KeyLength) - suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) - suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) suite.Equal(schema.DefaultPasswordConfig.Algorithm, suite.config.File.Password.Algorithm) - suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) - suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) + suite.Equal(schema.DefaultPasswordConfig.KeyLength, suite.config.File.Password.KeyLength) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) //nolint:staticcheck } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) - suite.config.File.Password = schema.Password{ + suite.config.File.Password = schema.AuthenticationBackendFilePassword{ Algorithm: digestSHA512, Iterations: 1000000, SaltLength: 8, @@ -121,14 +121,14 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512ButNotOverride() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) - suite.config.File.Password = schema.Password{ + suite.config.File.Password = schema.AuthenticationBackendFilePassword{ Algorithm: digestSHA512, Iterations: 1000000, SaltLength: 8, - SHA2Crypt: schema.SHA2CryptPassword{ + SHA2Crypt: schema.AuthenticationBackendFilePasswordSHA2Crypt{ Variant: digestSHA256, Iterations: 50000, SaltLength: 12, @@ -147,10 +147,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512Alt() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) - suite.config.File.Password = schema.Password{ + suite.config.File.Password = schema.AuthenticationBackendFilePassword{ Algorithm: digestSHA512, Iterations: 1000000, SaltLength: 64, @@ -168,10 +168,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) - suite.config.File.Password = schema.Password{ + suite.config.File.Password = schema.AuthenticationBackendFilePassword{ Algorithm: "argon2id", Iterations: 4, Memory: 1024, @@ -195,17 +195,17 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2ButNotOverride() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) - suite.config.File.Password = schema.Password{ + suite.config.File.Password = schema.AuthenticationBackendFilePassword{ Algorithm: "argon2id", Iterations: 4, Memory: 1024, Parallelism: 4, KeyLength: 64, SaltLength: 64, - Argon2: schema.Argon2Password{ + Argon2: schema.AuthenticationBackendFilePasswordArgon2{ Variant: "argon2d", Iterations: 1, Memory: 2048, @@ -230,7 +230,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationWhenOnlySHA512Set() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = digestSHA512 @@ -246,7 +246,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidArgon2Variant() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = "argon2" suite.config.File.Password.Argon2.Variant = testInvalid @@ -260,7 +260,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidArgon2 } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptVariant() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = hashSHA2Crypt suite.config.File.Password.SHA2Crypt.Variant = testInvalid @@ -274,7 +274,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2Cr } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptSaltLength() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = hashSHA2Crypt suite.config.File.Password.SHA2Crypt.SaltLength = 40 @@ -288,7 +288,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2Cr } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidPBKDF2Variant() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = "pbkdf2" suite.config.File.Password.PBKDF2.Variant = testInvalid @@ -302,7 +302,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidPBKDF2 } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidBCryptVariant() { - suite.config.File.Password = schema.Password{} + suite.config.File.Password = schema.AuthenticationBackendFilePassword{} suite.Equal("", suite.config.File.Password.Algorithm) suite.config.File.Password.Algorithm = "bcrypt" suite.config.File.Password.BCrypt.Variant = testInvalid @@ -502,10 +502,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenBadAlgorith func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() { suite.config.File.Password.Algorithm = "" - suite.config.File.Password.Iterations = 0 - suite.config.File.Password.SaltLength = 0 - suite.config.File.Password.Memory = 0 - suite.config.File.Password.Parallelism = 0 + suite.config.File.Password.Iterations = 0 //nolint:staticcheck + suite.config.File.Password.SaltLength = 0 //nolint:staticcheck + suite.config.File.Password.Memory = 0 //nolint:staticcheck + suite.config.File.Password.Parallelism = 0 //nolint:staticcheck ValidateAuthenticationBackend(&suite.config, suite.validator) @@ -513,10 +513,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() { suite.Len(suite.validator.Errors(), 0) suite.Equal(schema.DefaultPasswordConfig.Algorithm, suite.config.File.Password.Algorithm) - suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) - suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) - suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) - suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) + suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) //nolint:staticcheck + suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) //nolint:staticcheck } func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenResetURLIsInvalid() { @@ -571,7 +571,7 @@ type LDAPAuthenticationBackendSuite struct { func (suite *LDAPAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationCustom suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -867,7 +867,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlacehol } func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersion() { - suite.config.LDAP.TLS = &schema.TLSConfig{MinimumVersion: schema.TLSVersion{}} + suite.config.LDAP.TLS = &schema.TLS{MinimumVersion: schema.TLSVersion{}} ValidateAuthenticationBackend(&suite.config, suite.validator) @@ -878,7 +878,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersi } func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowSSL30() { - suite.config.LDAP.TLS = &schema.TLSConfig{ + suite.config.LDAP.TLS = &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck } @@ -949,7 +949,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldErrorOnMissingMemberOfRDN } func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowTLSVerMinGreaterThanVerMax() { - suite.config.LDAP.TLS = &schema.TLSConfig{ + suite.config.LDAP.TLS = &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, } @@ -973,7 +973,7 @@ type ActiveDirectoryAuthenticationBackendSuite struct { func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationActiveDirectory suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -1034,7 +1034,7 @@ type RFC2307bisAuthenticationBackendSuite struct { func (suite *RFC2307bisAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationRFC2307bis suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -1085,7 +1085,7 @@ type FreeIPAAuthenticationBackendSuite struct { func (suite *FreeIPAAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationFreeIPA suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -1136,7 +1136,7 @@ type LLDAPAuthenticationBackendSuite struct { func (suite *LLDAPAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationLLDAP suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -1187,7 +1187,7 @@ type GLAuthAuthenticationBackendSuite struct { func (suite *GLAuthAuthenticationBackendSuite) SetupTest() { suite.validator = schema.NewStructValidator() suite.config = schema.AuthenticationBackend{} - suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP = &schema.AuthenticationBackendLDAP{} suite.config.LDAP.Implementation = schema.LDAPImplementationGLAuth suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.User = testLDAPUser @@ -1237,7 +1237,7 @@ type LDAPImplementationSuite struct { validator *schema.StructValidator } -func (suite *LDAPImplementationSuite) EqualImplementationDefaults(expected schema.LDAPAuthenticationBackend) { +func (suite *LDAPImplementationSuite) EqualImplementationDefaults(expected schema.AuthenticationBackendLDAP) { suite.Equal(expected.Timeout, suite.config.LDAP.Timeout) suite.Equal(expected.AdditionalUsersDN, suite.config.LDAP.AdditionalUsersDN) suite.Equal(expected.AdditionalGroupsDN, suite.config.LDAP.AdditionalGroupsDN) @@ -1253,7 +1253,7 @@ func (suite *LDAPImplementationSuite) EqualImplementationDefaults(expected schem suite.Equal(expected.Attributes.GroupName, suite.config.LDAP.Attributes.GroupName) } -func (suite *LDAPImplementationSuite) NotEqualImplementationDefaults(expected schema.LDAPAuthenticationBackend) { +func (suite *LDAPImplementationSuite) NotEqualImplementationDefaults(expected schema.AuthenticationBackendLDAP) { suite.NotEqual(expected.Timeout, suite.config.LDAP.Timeout) suite.NotEqual(expected.UsersFilter, suite.config.LDAP.UsersFilter) suite.NotEqual(expected.GroupsFilter, suite.config.LDAP.GroupsFilter) diff --git a/internal/configuration/validator/configuration_test.go b/internal/configuration/validator/configuration_test.go index d39de0ff2..6054e53c8 100644 --- a/internal/configuration/validator/configuration_test.go +++ b/internal/configuration/validator/configuration_test.go @@ -17,29 +17,29 @@ func newDefaultConfig() schema.Configuration { config.Log.Level = "info" config.Log.Format = "text" config.JWTSecret = testJWTSecret - config.AuthenticationBackend.File = &schema.FileAuthenticationBackend{ + config.AuthenticationBackend.File = &schema.AuthenticationBackendFile{ Path: "/a/path", } - config.AccessControl = schema.AccessControlConfiguration{ + config.AccessControl = schema.AccessControl{ DefaultPolicy: "two_factor", } - config.Session = schema.SessionConfiguration{ + config.Session = schema.Session{ Secret: "secret", - Cookies: []schema.SessionCookieConfiguration{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", - Domain: exampleDotCom, + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", }, + Domain: exampleDotCom, }, }, } config.Storage.EncryptionKey = testEncryptionKey - config.Storage.Local = &schema.LocalStorageConfiguration{ + config.Storage.Local = &schema.StorageLocal{ Path: "abc", } - config.Notifier = schema.NotifierConfiguration{ - FileSystem: &schema.FileSystemNotifierConfiguration{ + config.Notifier = schema.Notifier{ + FileSystem: &schema.NotifierFileSystem{ Filename: "/tmp/file", }, } @@ -69,7 +69,7 @@ func TestShouldAddDefaultAccessControl(t *testing.T) { config := newDefaultConfig() config.AccessControl.DefaultPolicy = "" - config.AccessControl.Rules = []schema.ACLRule{ + config.AccessControl.Rules = []schema.AccessControlRule{ { Policy: "bypass", Domains: []string{ @@ -179,7 +179,7 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldAllowConfiguredMethodTOTP", have: &schema.Configuration{ Default2FAMethod: "totp", - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ SecretKey: "a key", IntegrationKey: "another key", Hostname: "none", @@ -190,7 +190,7 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldAllowConfiguredMethodWebAuthn", have: &schema.Configuration{ Default2FAMethod: "webauthn", - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ SecretKey: "a key", IntegrationKey: "another key", Hostname: "none", @@ -201,7 +201,7 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldAllowConfiguredMethodMobilePush", have: &schema.Configuration{ Default2FAMethod: "mobile_push", - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ SecretKey: "a key", IntegrationKey: "another key", Hostname: "none", @@ -212,12 +212,12 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldNotAllowDisabledMethodTOTP", have: &schema.Configuration{ Default2FAMethod: "totp", - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ SecretKey: "a key", IntegrationKey: "another key", Hostname: "none", }, - TOTP: schema.TOTPConfiguration{Disable: true}, + TOTP: schema.TOTP{Disable: true}, }, expectedErrs: []string{ "option 'default_2fa_method' must be one of the enabled options 'webauthn' or 'mobile_push' but it's configured as 'totp'", @@ -227,12 +227,12 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldNotAllowDisabledMethodWebAuthn", have: &schema.Configuration{ Default2FAMethod: "webauthn", - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ SecretKey: "a key", IntegrationKey: "another key", Hostname: "none", }, - WebAuthn: schema.WebAuthnConfiguration{Disable: true}, + WebAuthn: schema.WebAuthn{Disable: true}, }, expectedErrs: []string{ "option 'default_2fa_method' must be one of the enabled options 'totp' or 'mobile_push' but it's configured as 'webauthn'", @@ -242,7 +242,7 @@ func TestValidateDefault2FAMethod(t *testing.T) { desc: "ShouldNotAllowDisabledMethodMobilePush", have: &schema.Configuration{ Default2FAMethod: "mobile_push", - DuoAPI: schema.DuoAPIConfiguration{Disable: true}, + DuoAPI: schema.DuoAPI{Disable: true}, }, expectedErrs: []string{ "option 'default_2fa_method' must be one of the enabled options 'totp' or 'webauthn' but it's configured as 'mobile_push'", diff --git a/internal/configuration/validator/duo_test.go b/internal/configuration/validator/duo_test.go index 21cdbf6b1..8d457199e 100644 --- a/internal/configuration/validator/duo_test.go +++ b/internal/configuration/validator/duo_test.go @@ -14,27 +14,27 @@ func TestValidateDuo(t *testing.T) { testCases := []struct { desc string have *schema.Configuration - expected schema.DuoAPIConfiguration + expected schema.DuoAPI errs []string }{ { desc: "ShouldDisableDuo", have: &schema.Configuration{}, - expected: schema.DuoAPIConfiguration{Disable: true}, + expected: schema.DuoAPI{Disable: true}, }, { desc: "ShouldDisableDuoConfigured", - have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{Disable: true, Hostname: "example.com"}}, - expected: schema.DuoAPIConfiguration{Disable: true, Hostname: "example.com"}, + have: &schema.Configuration{DuoAPI: schema.DuoAPI{Disable: true, Hostname: "example.com"}}, + expected: schema.DuoAPI{Disable: true, Hostname: "example.com"}, }, { desc: "ShouldNotDisableDuo", - have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ + have: &schema.Configuration{DuoAPI: schema.DuoAPI{ Hostname: "test", IntegrationKey: "test", SecretKey: "test", }}, - expected: schema.DuoAPIConfiguration{ + expected: schema.DuoAPI{ Hostname: "test", IntegrationKey: "test", SecretKey: "test", @@ -42,11 +42,11 @@ func TestValidateDuo(t *testing.T) { }, { desc: "ShouldDetectMissingSecretKey", - have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ + have: &schema.Configuration{DuoAPI: schema.DuoAPI{ Hostname: "test", IntegrationKey: "test", }}, - expected: schema.DuoAPIConfiguration{ + expected: schema.DuoAPI{ Hostname: "test", IntegrationKey: "test", }, @@ -56,11 +56,11 @@ func TestValidateDuo(t *testing.T) { }, { desc: "ShouldDetectMissingIntegrationKey", - have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ + have: &schema.Configuration{DuoAPI: schema.DuoAPI{ Hostname: "test", SecretKey: "test", }}, - expected: schema.DuoAPIConfiguration{ + expected: schema.DuoAPI{ Hostname: "test", SecretKey: "test", }, @@ -70,11 +70,11 @@ func TestValidateDuo(t *testing.T) { }, { desc: "ShouldDetectMissingHostname", - have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ + have: &schema.Configuration{DuoAPI: schema.DuoAPI{ IntegrationKey: "test", SecretKey: "test", }}, - expected: schema.DuoAPIConfiguration{ + expected: schema.DuoAPI{ IntegrationKey: "test", SecretKey: "test", }, diff --git a/internal/configuration/validator/identity_providers.go b/internal/configuration/validator/identity_providers.go index 77a29ccc6..c08bded2c 100644 --- a/internal/configuration/validator/identity_providers.go +++ b/internal/configuration/validator/identity_providers.go @@ -22,7 +22,7 @@ func ValidateIdentityProviders(config *schema.IdentityProviders, val *schema.Str validateOIDC(config.OIDC, val) } -func validateOIDC(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDC(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { if config == nil { return } @@ -58,7 +58,7 @@ func validateOIDC(config *schema.OpenIDConnect, val *schema.StructValidator) { } } -func validateOIDCIssuer(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCIssuer(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch { case config.IssuerPrivateKey != nil: validateOIDCIssuerPrivateKey(config) @@ -71,7 +71,7 @@ func validateOIDCIssuer(config *schema.OpenIDConnect, val *schema.StructValidato } } -func validateOIDCIssuerPrivateKey(config *schema.OpenIDConnect) { +func validateOIDCIssuerPrivateKey(config *schema.IdentityProvidersOpenIDConnect) { config.IssuerPrivateKeys = append([]schema.JWK{{ Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, @@ -80,7 +80,7 @@ func validateOIDCIssuerPrivateKey(config *schema.OpenIDConnect) { }}, config.IssuerPrivateKeys...) } -func validateOIDCIssuerPrivateKeys(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCIssuerPrivateKeys(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { var ( props *JWKProperties err error @@ -132,7 +132,7 @@ func validateOIDCIssuerPrivateKeys(config *schema.OpenIDConnect, val *schema.Str } } -func validateOIDCIssuerPrivateKeysUseAlg(i int, props *JWKProperties, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCIssuerPrivateKeysUseAlg(i int, props *JWKProperties, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch config.IssuerPrivateKeys[i].Use { case "": config.IssuerPrivateKeys[i].Use = props.Use @@ -164,7 +164,7 @@ func validateOIDCIssuerPrivateKeysUseAlg(i int, props *JWKProperties, config *sc } } -func validateOIDCIssuerPrivateKeyPair(i int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCIssuerPrivateKeyPair(i int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { var ( checkEqualKey bool err error @@ -196,7 +196,7 @@ func validateOIDCIssuerPrivateKeyPair(i int, config *schema.OpenIDConnect, val * } } -func setOIDCDefaults(config *schema.OpenIDConnect) { +func setOIDCDefaults(config *schema.IdentityProvidersOpenIDConnect) { if config.AccessTokenLifespan == time.Duration(0) { config.AccessTokenLifespan = schema.DefaultOpenIDConnectConfiguration.AccessTokenLifespan } @@ -218,7 +218,7 @@ func setOIDCDefaults(config *schema.OpenIDConnect) { } } -func validateOIDCOptionsCORS(config *schema.OpenIDConnect, validator *schema.StructValidator) { +func validateOIDCOptionsCORS(config *schema.IdentityProvidersOpenIDConnect, validator *schema.StructValidator) { validateOIDCOptionsCORSAllowedOrigins(config, validator) if config.CORS.AllowedOriginsFromClientRedirectURIs { @@ -228,7 +228,7 @@ func validateOIDCOptionsCORS(config *schema.OpenIDConnect, validator *schema.Str validateOIDCOptionsCORSEndpoints(config, validator) } -func validateOIDCOptionsCORSAllowedOrigins(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCOptionsCORSAllowedOrigins(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { for _, origin := range config.CORS.AllowedOrigins { if origin.String() == "*" { if len(config.CORS.AllowedOrigins) != 1 { @@ -252,7 +252,7 @@ func validateOIDCOptionsCORSAllowedOrigins(config *schema.OpenIDConnect, val *sc } } -func validateOIDCOptionsCORSAllowedOriginsFromClientRedirectURIs(config *schema.OpenIDConnect) { +func validateOIDCOptionsCORSAllowedOriginsFromClientRedirectURIs(config *schema.IdentityProvidersOpenIDConnect) { for _, client := range config.Clients { for _, redirectURI := range client.RedirectURIs { uri, err := url.ParseRequestURI(redirectURI) @@ -269,7 +269,7 @@ func validateOIDCOptionsCORSAllowedOriginsFromClientRedirectURIs(config *schema. } } -func validateOIDCOptionsCORSEndpoints(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCOptionsCORSEndpoints(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { for _, endpoint := range config.CORS.Endpoints { if !utils.IsStringInSlice(endpoint, validOIDCCORSEndpoints) { val.Push(fmt.Errorf(errFmtOIDCCORSInvalidEndpoint, endpoint, strJoinOr(validOIDCCORSEndpoints))) @@ -277,7 +277,7 @@ func validateOIDCOptionsCORSEndpoints(config *schema.OpenIDConnect, val *schema. } } -func validateOIDCClients(config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClients(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { var ( errDeprecated bool @@ -319,7 +319,7 @@ func validateOIDCClients(config *schema.OpenIDConnect, val *schema.StructValidat } } -func validateOIDCClient(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClient(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { if config.Clients[c].Public { if config.Clients[c].Secret != nil { val.Push(fmt.Errorf(errFmtOIDCClientPublicInvalidSecret, config.Clients[c].ID)) @@ -369,7 +369,7 @@ func validateOIDCClient(c int, config *schema.OpenIDConnect, val *schema.StructV validateOIDCClientTokenEndpointAuth(c, config, val) } -func validateOIDCClientPublicKeys(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientPublicKeys(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch { case config.Clients[c].PublicKeys.URI != nil && len(config.Clients[c].PublicKeys.Values) != 0: val.Push(fmt.Errorf(errFmtOIDCClientPublicKeysBothURIAndValuesConfigured, config.Clients[c].ID)) @@ -382,7 +382,7 @@ func validateOIDCClientPublicKeys(c int, config *schema.OpenIDConnect, val *sche } } -func validateOIDCClientJSONWebKeysList(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientJSONWebKeysList(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { var ( props *JWKProperties err error @@ -440,7 +440,7 @@ func validateOIDCClientJSONWebKeysList(c int, config *schema.OpenIDConnect, val } } -func validateOIDCClientJSONWebKeysListKeyUseAlg(c, i int, props *JWKProperties, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientJSONWebKeysListKeyUseAlg(c, i int, props *JWKProperties, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch config.Clients[c].PublicKeys.Values[i].Use { case "": config.Clients[c].PublicKeys.Values[i].Use = props.Use @@ -470,7 +470,7 @@ func validateOIDCClientJSONWebKeysListKeyUseAlg(c, i int, props *JWKProperties, } } -func validateOIDCClientSectorIdentifier(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientSectorIdentifier(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { if config.Clients[c].SectorIdentifier.String() != "" { if utils.IsURLHostComponent(config.Clients[c].SectorIdentifier) || utils.IsURLHostComponentWithPort(config.Clients[c].SectorIdentifier) { return @@ -506,7 +506,7 @@ func validateOIDCClientSectorIdentifier(c int, config *schema.OpenIDConnect, val } } -func validateOIDCClientConsentMode(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientConsentMode(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch { case utils.IsStringInSlice(config.Clients[c].ConsentMode, []string{"", auto}): if config.Clients[c].ConsentPreConfiguredDuration != nil { @@ -525,7 +525,7 @@ func validateOIDCClientConsentMode(c int, config *schema.OpenIDConnect, val *sch } } -func validateOIDCClientScopes(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientScopes(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { if len(config.Clients[c].Scopes) == 0 { config.Clients[c].Scopes = schema.DefaultOpenIDConnectClientConfiguration.Scopes } @@ -558,7 +558,7 @@ func validateOIDCClientScopes(c int, config *schema.OpenIDConnect, val *schema.S } } -func validateOIDCClientResponseTypes(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientResponseTypes(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { if len(config.Clients[c].ResponseTypes) == 0 { config.Clients[c].ResponseTypes = schema.DefaultOpenIDConnectClientConfiguration.ResponseTypes } @@ -576,7 +576,7 @@ func validateOIDCClientResponseTypes(c int, config *schema.OpenIDConnect, val *s } } -func validateOIDCClientResponseModes(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientResponseModes(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { if len(config.Clients[c].ResponseModes) == 0 { config.Clients[c].ResponseModes = schema.DefaultOpenIDConnectClientConfiguration.ResponseModes @@ -608,7 +608,7 @@ func validateOIDCClientResponseModes(c int, config *schema.OpenIDConnect, val *s } } -func validateOIDCClientGrantTypes(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientGrantTypes(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { if len(config.Clients[c].GrantTypes) == 0 { validateOIDCClientGrantTypesSetDefaults(c, config) } @@ -628,7 +628,7 @@ func validateOIDCClientGrantTypes(c int, config *schema.OpenIDConnect, val *sche } } -func validateOIDCClientGrantTypesSetDefaults(c int, config *schema.OpenIDConnect) { +func validateOIDCClientGrantTypesSetDefaults(c int, config *schema.IdentityProvidersOpenIDConnect) { for _, responseType := range config.Clients[c].ResponseTypes { switch responseType { case oidc.ResponseTypeAuthorizationCodeFlow: @@ -651,7 +651,7 @@ func validateOIDCClientGrantTypesSetDefaults(c int, config *schema.OpenIDConnect } } -func validateOIDCClientGrantTypesCheckRelated(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientGrantTypesCheckRelated(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { for _, grantType := range config.Clients[c].GrantTypes { switch grantType { case oidc.GrantTypeImplicit: @@ -686,7 +686,7 @@ func validateOIDCClientGrantTypesCheckRelated(c int, config *schema.OpenIDConnec } } -func validateOIDCClientRedirectURIs(c int, config *schema.OpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { +func validateOIDCClientRedirectURIs(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator, errDeprecatedFunc func()) { var ( parsedRedirectURI *url.URL err error @@ -723,7 +723,7 @@ func validateOIDCClientRedirectURIs(c int, config *schema.OpenIDConnect, val *sc } } -func validateOIDCClientTokenEndpointAuth(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientTokenEndpointAuth(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { implcit := len(config.Clients[c].ResponseTypes) != 0 && utils.IsStringSliceContainsAll(config.Clients[c].ResponseTypes, validOIDCClientResponseTypesImplicitFlow) switch { @@ -750,7 +750,7 @@ func validateOIDCClientTokenEndpointAuth(c int, config *schema.OpenIDConnect, va } } -func validateOIDCClientTokenEndpointAuthClientSecretJWT(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDCClientTokenEndpointAuthClientSecretJWT(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch { case config.Clients[c].TokenEndpointAuthSigningAlg == "": config.Clients[c].TokenEndpointAuthSigningAlg = oidc.SigningAlgHMACUsingSHA256 @@ -759,7 +759,7 @@ func validateOIDCClientTokenEndpointAuthClientSecretJWT(c int, config *schema.Op } } -func validateOIDCClientTokenEndpointAuthPublicKeyJWT(config schema.OpenIDConnectClient, val *schema.StructValidator) { +func validateOIDCClientTokenEndpointAuthPublicKeyJWT(config schema.IdentityProvidersOpenIDConnectClient, val *schema.StructValidator) { switch { case config.TokenEndpointAuthSigningAlg == "": val.Push(fmt.Errorf(errFmtOIDCClientInvalidTokenEndpointAuthSigAlgMissingPrivateKeyJWT, config.ID)) @@ -776,7 +776,7 @@ func validateOIDCClientTokenEndpointAuthPublicKeyJWT(config schema.OpenIDConnect } } -func validateOIDDClientSigningAlgs(c int, config *schema.OpenIDConnect, val *schema.StructValidator) { +func validateOIDDClientSigningAlgs(c int, config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) { switch config.Clients[c].UserinfoSigningKeyID { case "": if config.Clients[c].UserinfoSigningAlg == "" { diff --git a/internal/configuration/validator/identity_providers_test.go b/internal/configuration/validator/identity_providers_test.go index a282f049f..f90ef24bd 100644 --- a/internal/configuration/validator/identity_providers_test.go +++ b/internal/configuration/validator/identity_providers_test.go @@ -24,7 +24,7 @@ import ( func TestShouldRaiseErrorWhenInvalidOIDCServerConfiguration(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "abc", }, } @@ -40,13 +40,13 @@ func TestShouldRaiseErrorWhenInvalidOIDCServerConfiguration(t *testing.T) { func TestShouldNotRaiseErrorWhenCORSEndpointsValid(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, - CORS: schema.OpenIDConnectCORS{ + CORS: schema.IdentityProvidersOpenIDConnectCORS{ Endpoints: []string{oidc.EndpointAuthorization, oidc.EndpointToken, oidc.EndpointIntrospection, oidc.EndpointRevocation, oidc.EndpointUserinfo}, }, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "example", Secret: tOpenIDConnectPlainTextClientSecret, @@ -63,13 +63,13 @@ func TestShouldNotRaiseErrorWhenCORSEndpointsValid(t *testing.T) { func TestShouldRaiseErrorWhenCORSEndpointsNotValid(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, - CORS: schema.OpenIDConnectCORS{ + CORS: schema.IdentityProvidersOpenIDConnectCORS{ Endpoints: []string{oidc.EndpointAuthorization, oidc.EndpointToken, oidc.EndpointIntrospection, oidc.EndpointRevocation, oidc.EndpointUserinfo, "invalid_endpoint"}, }, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "example", Secret: tOpenIDConnectPlainTextClientSecret, @@ -88,7 +88,7 @@ func TestShouldRaiseErrorWhenCORSEndpointsNotValid(t *testing.T) { func TestShouldRaiseErrorWhenOIDCPKCEEnforceValueInvalid(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, EnforcePKCE: testInvalid, @@ -107,14 +107,14 @@ func TestShouldRaiseErrorWhenOIDCCORSOriginsHasInvalidValues(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, - CORS: schema.OpenIDConnectCORS{ + CORS: schema.IdentityProvidersOpenIDConnectCORS{ AllowedOrigins: utils.URLsFromStringSlice([]string{"https://example.com/", "https://site.example.com/subpath", "https://site.example.com?example=true", "*"}), AllowedOriginsFromClientRedirectURIs: true, }, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "myclient", Secret: tOpenIDConnectPlainTextClientSecret, @@ -142,7 +142,7 @@ func TestShouldRaiseErrorWhenOIDCCORSOriginsHasInvalidValues(t *testing.T) { func TestShouldRaiseErrorWhenOIDCServerNoClients(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, }, @@ -167,12 +167,12 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { testCases := []struct { Name string - Clients []schema.OpenIDConnectClient + Clients []schema.IdentityProvidersOpenIDConnectClient Errors []string }{ { Name: "EmptyIDAndSecret", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "", Secret: nil, @@ -187,7 +187,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidPolicy", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-1", Secret: tOpenIDConnectPlainTextClientSecret, @@ -203,7 +203,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "ClientIDDuplicated", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-x", Secret: tOpenIDConnectPlainTextClientSecret, @@ -223,7 +223,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "RedirectURIInvalid", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-check-uri-parse", Secret: tOpenIDConnectPlainTextClientSecret, @@ -239,7 +239,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "RedirectURINotAbsolute", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-check-uri-abs", Secret: tOpenIDConnectPlainTextClientSecret, @@ -255,7 +255,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "ValidSectorIdentifier", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-valid-sector", Secret: tOpenIDConnectPlainTextClientSecret, @@ -269,7 +269,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "ValidSectorIdentifierWithPort", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-valid-sector", Secret: tOpenIDConnectPlainTextClientSecret, @@ -283,7 +283,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidSectorIdentifierInvalidURL", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-invalid-sector", Secret: tOpenIDConnectPlainTextClientSecret, @@ -305,7 +305,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidSectorIdentifierInvalidHost", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-invalid-sector", Secret: tOpenIDConnectPlainTextClientSecret, @@ -322,7 +322,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidConsentMode", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-bad-consent-mode", Secret: tOpenIDConnectPlainTextClientSecret, @@ -339,7 +339,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidPKCEChallengeMethod", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-bad-pkce-mode", Secret: tOpenIDConnectPlainTextClientSecret, @@ -356,7 +356,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { }, { Name: "InvalidPKCEChallengeMethodLowerCaseS256", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-bad-pkce-mode-s256", Secret: tOpenIDConnectPlainTextClientSecret, @@ -377,7 +377,7 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { t.Run(tc.Name, func(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, Clients: tc.Clients, @@ -401,10 +401,10 @@ func TestShouldRaiseErrorWhenOIDCServerClientBadValues(t *testing.T) { func TestShouldRaiseErrorWhenOIDCClientConfiguredWithBadScopes(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "good_id", Secret: tOpenIDConnectPlainTextClientSecret, @@ -427,10 +427,10 @@ func TestShouldRaiseErrorWhenOIDCClientConfiguredWithBadScopes(t *testing.T) { func TestShouldRaiseErrorWhenOIDCClientConfiguredWithBadGrantTypes(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "good_id", Secret: tOpenIDConnectPBKDF2ClientSecret, @@ -453,11 +453,11 @@ func TestShouldRaiseErrorWhenOIDCClientConfiguredWithBadGrantTypes(t *testing.T) func TestShouldNotErrorOnCertificateValid(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerCertificateChain: certRSA2048, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "good_id", Secret: tOpenIDConnectPBKDF2ClientSecret, @@ -479,11 +479,11 @@ func TestShouldNotErrorOnCertificateValid(t *testing.T) { func TestShouldRaiseErrorOnCertificateNotValid(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "rLABDrx87et5KvRHVUgTm3pezWWd8LMN", IssuerCertificateChain: certRSA2048, IssuerPrivateKey: keyRSA4096, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "good_id", Secret: tOpenIDConnectPBKDF2ClientSecret, @@ -553,11 +553,11 @@ func TestValidateIdentityProvidersOpenIDConnectMinimumParameterEntropy(t *testin t.Run(tc.name, func(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "abc", IssuerPrivateKey: keyRSA2048, MinimumParameterEntropy: tc.have, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "good_id", Secret: tOpenIDConnectPBKDF2ClientSecret, @@ -600,10 +600,10 @@ func TestValidateIdentityProvidersOpenIDConnectMinimumParameterEntropy(t *testin func TestValidateIdentityProvidersShouldRaiseErrorsOnInvalidClientTypes(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "hmac1", IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-with-invalid-secret", Secret: tOpenIDConnectPlainTextClientSecret, @@ -638,10 +638,10 @@ func TestValidateIdentityProvidersShouldRaiseErrorsOnInvalidClientTypes(t *testi func TestValidateIdentityProvidersShouldNotRaiseErrorsOnValidClientOptions(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "hmac1", IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "installed-app-client", Public: true, @@ -697,10 +697,10 @@ func TestValidateIdentityProvidersShouldNotRaiseErrorsOnValidClientOptions(t *te func TestValidateIdentityProvidersShouldRaiseWarningOnPlainTextClients(t *testing.T) { validator := schema.NewStructValidator() config := &schema.IdentityProviders{ - OIDC: &schema.OpenIDConnect{ + OIDC: &schema.IdentityProvidersOpenIDConnect{ HMACSecret: "hmac1", IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "client-with-invalid-secret_standard", Secret: tOpenIDConnectPlainTextClientSecret, @@ -723,8 +723,8 @@ func TestValidateIdentityProvidersShouldRaiseWarningOnPlainTextClients(t *testin // All valid schemes are supported as defined in https://datatracker.ietf.org/doc/html/rfc8252#section-7.1 func TestValidateOIDCClientRedirectURIsSupportingPrivateUseURISchemes(t *testing.T) { - have := &schema.OpenIDConnect{ - Clients: []schema.OpenIDConnectClient{ + have := &schema.IdentityProvidersOpenIDConnect{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "owncloud", RedirectURIs: []string{ @@ -771,8 +771,8 @@ func TestValidateOIDCClients(t *testing.T) { testCasses := []struct { name string - setup func(have *schema.OpenIDConnect) - validate func(t *testing.T, have *schema.OpenIDConnect) + setup func(have *schema.IdentityProvidersOpenIDConnect) + validate func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) have tcv expected tcv serrs []string // Soft errors which will be warnings before GA. @@ -1225,13 +1225,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldValidateCorrectRedirectURIsConfidentialClientType", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].RedirectURIs = []string{ "https://google.com", } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{"https://google.com"}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{"https://google.com"}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1250,15 +1250,15 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldValidateCorrectRedirectURIsPublicClientType", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].Public = true have.Clients[0].Secret = nil have.Clients[0].RedirectURIs = []string{ oauth2InstalledApp, } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{oauth2InstalledApp}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{oauth2InstalledApp}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1277,13 +1277,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidRedirectURIsPublicOnly", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].RedirectURIs = []string{ "urn:ietf:wg:oauth:2.0:oob", } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{oauth2InstalledApp}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{oauth2InstalledApp}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1304,13 +1304,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidRedirectURIsMalformedURI", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].RedirectURIs = []string{ "http://abc@%two", } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{"http://abc@%two"}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{"http://abc@%two"}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1331,13 +1331,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidRedirectURIsNotAbsolute", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].RedirectURIs = []string{ "google.com", } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{"google.com"}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{"google.com"}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1358,14 +1358,14 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnDuplicateRedirectURI", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].RedirectURIs = []string{ "https://google.com", "https://google.com", } }, - func(t *testing.T, have *schema.OpenIDConnect) { - assert.Equal(t, []string{"https://google.com", "https://google.com"}, have.Clients[0].RedirectURIs) + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { + assert.Equal(t, schema.IdentityProvidersOpenIDConnectClientRedirectURIs([]string{"https://google.com", "https://google.com"}), have.Clients[0].RedirectURIs) }, tcv{ nil, @@ -1387,7 +1387,7 @@ func TestValidateOIDCClients(t *testing.T) { { "ShouldNotSetDefaultTokenEndpointClientAuthMethodConfidentialClientType", nil, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "", have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1407,10 +1407,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldNotOverrideValidClientAuthMethod", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretPost }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.ClientAuthMethodClientSecretPost, have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1430,10 +1430,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidClientAuthMethod", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = "client_credentials" }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "client_credentials", have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1455,12 +1455,12 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidClientAuthMethodForPublicClientType", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretBasic have.Clients[0].Public = true have.Clients[0].Secret = nil }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.ClientAuthMethodClientSecretBasic, have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1482,10 +1482,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidClientAuthMethodForConfidentialClientTypeAuthorizationCodeFlow", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodNone }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.ClientAuthMethodNone, have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1507,10 +1507,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidClientAuthMethodForConfidentialClientTypeHybridFlow", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodNone }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.ClientAuthMethodNone, have.Clients[0].TokenEndpointAuthMethod) }, tcv{ @@ -1533,7 +1533,7 @@ func TestValidateOIDCClients(t *testing.T) { { "ShouldSetDefaultUserInfoAlg", nil, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.SigningAlgNone, have.Clients[0].UserinfoSigningAlg) }, tcv{ @@ -1553,10 +1553,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldNotOverrideUserInfoAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].UserinfoSigningAlg = oidc.SigningAlgRSAUsingSHA256 }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.SigningAlgRSAUsingSHA256, have.Clients[0].UserinfoSigningAlg) }, tcv{ @@ -1576,10 +1576,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidUserInfoSigningAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].UserinfoSigningAlg = rs256 }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, rs256, have.Clients[0].UserinfoSigningAlg) }, tcv{ @@ -1601,10 +1601,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidIDTokenSigningAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].IDTokenSigningAlg = rs256 }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, rs256, have.Clients[0].IDTokenSigningAlg) }, tcv{ @@ -1627,7 +1627,7 @@ func TestValidateOIDCClients(t *testing.T) { { "ShouldSetDefaultConsentMode", nil, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "explicit", have.Clients[0].ConsentMode) }, tcv{ @@ -1647,10 +1647,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSetDefaultConsentModeAuto", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].ConsentMode = auto }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "explicit", have.Clients[0].ConsentMode) }, tcv{ @@ -1670,13 +1670,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSetDefaultConsentModePreConfigured", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { d := time.Minute have.Clients[0].ConsentMode = "" have.Clients[0].ConsentPreConfiguredDuration = &d }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "pre-configured", have.Clients[0].ConsentMode) }, tcv{ @@ -1696,13 +1696,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSetDefaultConsentModeAutoPreConfigured", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { d := time.Minute have.Clients[0].ConsentMode = auto have.Clients[0].ConsentPreConfiguredDuration = &d }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "pre-configured", have.Clients[0].ConsentMode) }, tcv{ @@ -1722,10 +1722,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldNotOverrideConsentMode", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].ConsentMode = "implicit" }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "implicit", have.Clients[0].ConsentMode) }, tcv{ @@ -1745,10 +1745,10 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSentConsentPreConfiguredDefaultDuration", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].ConsentMode = "pre-configured" }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, "pre-configured", have.Clients[0].ConsentMode) assert.Equal(t, schema.DefaultOpenIDConnectClientConfiguration.ConsentPreConfiguredDuration, have.Clients[0].ConsentPreConfiguredDuration) }, @@ -1769,7 +1769,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnTokenEndpointClientAuthMethodPrivateKeyJWTMustSetAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodPrivateKeyJWT have.Clients[0].Secret = tOpenIDConnectPBKDF2ClientSecret }, @@ -1794,7 +1794,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnTokenEndpointClientAuthMethodPrivateKeyJWTMustSetAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodPrivateKeyJWT have.Clients[0].TokenEndpointAuthSigningAlg = "nope" have.Clients[0].Secret = tOpenIDConnectPBKDF2ClientSecret @@ -1820,7 +1820,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnTokenEndpointClientAuthMethodPrivateKeyJWTMustSetKnownAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodPrivateKeyJWT have.Clients[0].TokenEndpointAuthSigningAlg = oidc.SigningAlgECDSAUsingP384AndSHA384 have.Clients[0].Secret = tOpenIDConnectPBKDF2ClientSecret @@ -1852,7 +1852,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnTokenEndpointClientAuthMethodPrivateKeyJWTMustSetKnownAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodPrivateKeyJWT have.Clients[0].TokenEndpointAuthSigningAlg = oidc.SigningAlgECDSAUsingP384AndSHA384 have.Clients[0].Secret = tOpenIDConnectPBKDF2ClientSecret @@ -1877,7 +1877,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnIncorrectlyConfiguredTokenEndpointClientAuthMethodClientSecretJWT", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].Secret = tOpenIDConnectPBKDF2ClientSecret }, @@ -1901,7 +1901,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldNotRaiseWarningOrErrorOnCorrectlyConfiguredTokenEndpointClientAuthMethodClientSecretJWT", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].Secret = tOpenIDConnectPlainTextClientSecret }, @@ -1923,7 +1923,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnIncorrectlyConfiguredTokenEndpointClientAuthMethodClientSecretJWT", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].Secret = MustDecodeSecret("$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng") }, @@ -1947,7 +1947,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldNotRaiseWarningOrErrorOnCorrectlyConfiguredTokenEndpointClientAuthMethodClientSecretJWT", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].Secret = MustDecodeSecret("$plaintext$abc123") }, @@ -1969,7 +1969,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSetValidDefaultKeyID", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].IDTokenSigningKeyID = "abcabc123" have.Clients[0].UserinfoSigningKeyID = "abc123abc" have.Discovery.ResponseObjectSigningKeyIDs = []string{"abcabc123", "abc123abc"} @@ -1992,7 +1992,7 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidKeyID", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].IDTokenSigningKeyID = "ab" have.Clients[0].UserinfoSigningKeyID = "cd" have.Discovery.ResponseObjectSigningKeyIDs = []string{"abc123xyz"} @@ -2018,11 +2018,11 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldSetDefaultTokenEndpointAuthSigAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].Secret = tOpenIDConnectPlainTextClientSecret }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.SigningAlgHMACUsingSHA256, have.Clients[0].TokenEndpointAuthSigningAlg) }, tcv{ @@ -2042,13 +2042,13 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidPublicTokenAuthAlg", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].TokenEndpointAuthSigningAlg = oidc.SigningAlgHMACUsingSHA256 have.Clients[0].Secret = nil have.Clients[0].Public = true }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.SigningAlgHMACUsingSHA256, have.Clients[0].TokenEndpointAuthSigningAlg) }, tcv{ @@ -2070,12 +2070,12 @@ func TestValidateOIDCClients(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidTokenAuthAlgClientTypeConfidential", - func(have *schema.OpenIDConnect) { + func(have *schema.IdentityProvidersOpenIDConnect) { have.Clients[0].TokenEndpointAuthMethod = oidc.ClientAuthMethodClientSecretJWT have.Clients[0].TokenEndpointAuthSigningAlg = oidc.EndpointToken have.Clients[0].Secret = tOpenIDConnectPlainTextClientSecret }, - func(t *testing.T, have *schema.OpenIDConnect) { + func(t *testing.T, have *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.EndpointToken, have.Clients[0].TokenEndpointAuthSigningAlg) }, tcv{ @@ -2101,11 +2101,11 @@ func TestValidateOIDCClients(t *testing.T) { for _, tc := range testCasses { t.Run(tc.name, func(t *testing.T) { - have := &schema.OpenIDConnect{ + have := &schema.IdentityProvidersOpenIDConnect{ Discovery: schema.OpenIDConnectDiscovery{ ResponseObjectSigningAlgs: []string{oidc.SigningAlgRSAUsingSHA256}, }, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "test", Secret: tOpenIDConnectPBKDF2ClientSecret, @@ -2181,8 +2181,8 @@ func TestValidateOIDCClientTokenEndpointAuthMethod(t *testing.T) { for _, tc := range testCasses { t.Run(tc.name, func(t *testing.T) { - have := &schema.OpenIDConnect{ - Clients: []schema.OpenIDConnectClient{ + have := &schema.IdentityProvidersOpenIDConnect{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "test", Public: tc.public, @@ -2220,8 +2220,8 @@ func TestValidateOIDCClientJWKS(t *testing.T) { name string haveURI *url.URL haveJWKS []schema.JWK - setup func(config *schema.OpenIDConnect) - expected func(t *testing.T, config *schema.OpenIDConnect) + setup func(config *schema.IdentityProvidersOpenIDConnect) + expected func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) errs []string }{ { @@ -2390,7 +2390,7 @@ func TestValidateOIDCClientJWKS(t *testing.T) { {KeyID: "test", Use: "", Algorithm: "", Key: keyRSA2048PKCS8.Public()}, }, nil, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgRSAUsingSHA256, config.Clients[0].PublicKeys.Values[0].Algorithm) }, @@ -2403,7 +2403,7 @@ func TestValidateOIDCClientJWKS(t *testing.T) { {KeyID: "test", Use: "", Algorithm: "", Key: keyECDSAP256.Public()}, }, nil, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgECDSAUsingP256AndSHA256, config.Clients[0].PublicKeys.Values[0].Algorithm) }, @@ -2416,7 +2416,7 @@ func TestValidateOIDCClientJWKS(t *testing.T) { {KeyID: "test", Use: "", Algorithm: "", Key: keyECDSAP384.Public()}, }, nil, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgECDSAUsingP384AndSHA384, config.Clients[0].PublicKeys.Values[0].Algorithm) }, @@ -2429,7 +2429,7 @@ func TestValidateOIDCClientJWKS(t *testing.T) { {KeyID: "test", Use: "", Algorithm: "", Key: keyECDSAP521.Public()}, }, nil, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgECDSAUsingP521AndSHA512, config.Clients[0].PublicKeys.Values[0].Algorithm) }, @@ -2442,7 +2442,7 @@ func TestValidateOIDCClientJWKS(t *testing.T) { {KeyID: "test", Use: "", Algorithm: "", Key: keyECDSAP521.Public()}, }, nil, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgECDSAUsingP521AndSHA512, config.Clients[0].PublicKeys.Values[0].Algorithm) @@ -2456,10 +2456,10 @@ func TestValidateOIDCClientJWKS(t *testing.T) { []schema.JWK{ {KeyID: "test", Use: "", Algorithm: "", Key: keyECDSAP521.Public()}, }, - func(config *schema.OpenIDConnect) { + func(config *schema.IdentityProvidersOpenIDConnect) { config.Clients[0].RequestObjectSigningAlg = oidc.SigningAlgRSAUsingSHA512 }, - func(t *testing.T, config *schema.OpenIDConnect) { + func(t *testing.T, config *schema.IdentityProvidersOpenIDConnect) { assert.Equal(t, oidc.KeyUseSignature, config.Clients[0].PublicKeys.Values[0].Use) assert.Equal(t, oidc.SigningAlgECDSAUsingP521AndSHA512, config.Clients[0].PublicKeys.Values[0].Algorithm) @@ -2473,11 +2473,11 @@ func TestValidateOIDCClientJWKS(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - config := &schema.OpenIDConnect{ - Clients: []schema.OpenIDConnectClient{ + config := &schema.IdentityProvidersOpenIDConnect{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "test", - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ URI: tc.haveURI, Values: tc.haveJWKS, }, @@ -2521,16 +2521,16 @@ func TestValidateOIDCIssuer(t *testing.T) { testCases := []struct { name string - have schema.OpenIDConnect - expected schema.OpenIDConnect + have schema.IdentityProvidersOpenIDConnect + expected schema.IdentityProvidersOpenIDConnect errs []string }{ { "ShouldMapLegacyConfiguration", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKey: keyRSA2048, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKey: keyRSA2048, IssuerPrivateKeys: []schema.JWK{ {KeyID: "1f8bfc", Key: keyRSA2048, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature}, @@ -2544,7 +2544,7 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldSetDefaultKeyValues", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: certRSA2048}, {Key: keyECDSAP256, CertificateChain: certECDSAP256}, @@ -2552,7 +2552,7 @@ func TestValidateOIDCIssuer(t *testing.T) { {Key: keyECDSAP521, CertificateChain: certECDSAP521}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: certRSA2048, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "1f8bfc"}, {Key: keyECDSAP256, CertificateChain: certECDSAP256, Algorithm: oidc.SigningAlgECDSAUsingP256AndSHA256, Use: oidc.KeyUseSignature, KeyID: "1e7788"}, @@ -2573,13 +2573,13 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldNotRaiseErrorsMultipleRSA256Keys", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: certRSA2048}, {Key: keyRSA4096, CertificateChain: certRSA4096}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: certRSA2048, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "1f8bfc"}, {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "bf1e10"}, @@ -2593,12 +2593,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorsDuplicateRSA256Keys", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA512}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA512, Use: oidc.KeyUseSignature, KeyID: "bf1e10"}, }, @@ -2613,13 +2613,13 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadCurve", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096}, {Key: keyECDSAP224, CertificateChain: certECDSAP224}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "bf1e10"}, {Key: keyECDSAP224, CertificateChain: certECDSAP224}, @@ -2635,12 +2635,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadRSAKey", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA1024, CertificateChain: certRSA1024}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA1024, CertificateChain: certRSA1024, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "cf375e"}, }, @@ -2655,12 +2655,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadAlg", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: "invalid"}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: "invalid", Use: oidc.KeyUseSignature, KeyID: "bf1e10"}, }, @@ -2676,12 +2676,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadUse", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Use: "invalid"}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: "invalid", KeyID: "bf1e10"}, }, @@ -2696,12 +2696,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadKeyIDLength", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "thisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolong"}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "thisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolongthisistoolong"}, }, @@ -2716,14 +2716,14 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadKeyIDCharacters", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "x@x"}, {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "-xx"}, {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "xx."}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "x@x"}, {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "-xx"}, @@ -2742,14 +2742,14 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldNotRaiseErrorOnGoodKeyIDCharacters", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "x-x"}, {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "x"}, {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "xx"}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "x-x"}, {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "x"}, @@ -2764,13 +2764,13 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnBadKeyIDDuplicates", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, KeyID: "x"}, {Key: keyRSA2048, CertificateChain: certRSA2048, Algorithm: oidc.SigningAlgRSAPSSUsingSHA256, KeyID: "x"}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA4096, CertificateChain: certRSA4096, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "x"}, {Key: keyRSA2048, CertificateChain: certRSA2048, Algorithm: oidc.SigningAlgRSAPSSUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "x"}, @@ -2786,12 +2786,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnEd25519Keys", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyEd2519, CertificateChain: certEd15519}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyEd2519, CertificateChain: certEd15519, KeyID: "14dfd3"}, }, @@ -2806,12 +2806,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnCertificateAsKey", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: publicRSA2048Pair}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: publicRSA2048Pair, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "9a0e71"}, }, @@ -2826,12 +2826,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidChain", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: frankenchain}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: frankenchain, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature, KeyID: "1f8bfc"}, }, @@ -2846,12 +2846,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnInvalidPrivateKeyN", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: frankenkey}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: frankenkey}, }, @@ -2866,12 +2866,12 @@ func TestValidateOIDCIssuer(t *testing.T) { }, { "ShouldRaiseErrorOnCertForKey", - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: certRSA2048}, }, }, - schema.OpenIDConnect{ + schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: certRSA2048}, }, diff --git a/internal/configuration/validator/log_test.go b/internal/configuration/validator/log_test.go index cf3de2736..3e7faa278 100644 --- a/internal/configuration/validator/log_test.go +++ b/internal/configuration/validator/log_test.go @@ -28,7 +28,7 @@ func TestShouldSetDefaultLoggingValues(t *testing.T) { func TestShouldRaiseErrorOnInvalidLoggingLevel(t *testing.T) { config := &schema.Configuration{ - Log: schema.LogConfiguration{ + Log: schema.Log{ Level: "TRACE", }, } diff --git a/internal/configuration/validator/notifier.go b/internal/configuration/validator/notifier.go index deb2bc24c..92398008b 100644 --- a/internal/configuration/validator/notifier.go +++ b/internal/configuration/validator/notifier.go @@ -8,7 +8,7 @@ import ( ) // ValidateNotifier validates and update notifier configuration. -func ValidateNotifier(config *schema.NotifierConfiguration, validator *schema.StructValidator) { +func ValidateNotifier(config *schema.Notifier, validator *schema.StructValidator) { if config.SMTP == nil && config.FileSystem == nil { validator.Push(fmt.Errorf(errFmtNotifierNotConfigured)) @@ -32,7 +32,7 @@ func ValidateNotifier(config *schema.NotifierConfiguration, validator *schema.St validateNotifierTemplates(config, validator) } -func validateNotifierTemplates(config *schema.NotifierConfiguration, validator *schema.StructValidator) { +func validateNotifierTemplates(config *schema.Notifier, validator *schema.StructValidator) { if config.TemplatePath == "" { return } @@ -47,7 +47,7 @@ func validateNotifierTemplates(config *schema.NotifierConfiguration, validator * } } -func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *schema.StructValidator) { +func validateSMTPNotifier(config *schema.NotifierSMTP, validator *schema.StructValidator) { validateSMTPNotifierAddress(config, validator) if config.StartupCheckAddress.Address == "" { @@ -71,10 +71,10 @@ func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *s } if config.TLS == nil { - config.TLS = &schema.TLSConfig{} + config.TLS = &schema.TLS{} } - configDefaultTLS := &schema.TLSConfig{ + configDefaultTLS := &schema.TLS{ MinimumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MinimumVersion, MaximumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MaximumVersion, } @@ -92,7 +92,7 @@ func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *s } } -func validateSMTPNotifierAddress(config *schema.SMTPNotifierConfiguration, validator *schema.StructValidator) { +func validateSMTPNotifierAddress(config *schema.NotifierSMTP, validator *schema.StructValidator) { if config.Address == nil { if config.Host == "" && config.Port == 0 { //nolint:staticcheck validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "address")) diff --git a/internal/configuration/validator/notifier_test.go b/internal/configuration/validator/notifier_test.go index f2d39d5f5..d01746b4b 100644 --- a/internal/configuration/validator/notifier_test.go +++ b/internal/configuration/validator/notifier_test.go @@ -16,13 +16,13 @@ import ( type NotifierSuite struct { suite.Suite - config schema.NotifierConfiguration + config schema.Notifier validator *schema.StructValidator } func (suite *NotifierSuite) SetupTest() { suite.validator = schema.NewStructValidator() - suite.config.SMTP = &schema.SMTPNotifierConfiguration{ + suite.config.SMTP = &schema.NotifierSMTP{ Address: &schema.AddressSMTP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeSMTP, exampleDotCom, 25)}, Username: "john", Password: "password", @@ -57,7 +57,7 @@ func (suite *NotifierSuite) TestShouldEnsureEitherSMTPOrFilesystemIsProvided() { suite.Len(suite.validator.Errors(), 0) - suite.config.FileSystem = &schema.FileSystemNotifierConfiguration{ + suite.config.FileSystem = &schema.NotifierFileSystem{ Filename: "test", } @@ -147,7 +147,7 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultStartupCheckAddress() { func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() { suite.config.SMTP.Address.SetHostname("google.com") - suite.config.SMTP.TLS = &schema.TLSConfig{ + suite.config.SMTP.TLS = &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, } @@ -162,7 +162,7 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() { } func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() { - suite.config.SMTP.TLS = &schema.TLSConfig{ + suite.config.SMTP.TLS = &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck } @@ -175,7 +175,7 @@ func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() { } func (suite *NotifierSuite) TestSMTPShouldErrorOnTLSMinVerGreaterThanMaxVer() { - suite.config.SMTP.TLS = &schema.TLSConfig{ + suite.config.SMTP.TLS = &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10}, } @@ -262,7 +262,7 @@ File Tests. */ func (suite *NotifierSuite) TestFileShouldEnsureFilenameIsProvided() { suite.config.SMTP = nil - suite.config.FileSystem = &schema.FileSystemNotifierConfiguration{ + suite.config.FileSystem = &schema.NotifierFileSystem{ Filename: "test", } ValidateNotifier(&suite.config, suite.validator) @@ -287,7 +287,7 @@ func TestNotifierSuite(t *testing.T) { } func TestNotifierMiscMissingTemplateTests(t *testing.T) { - config := &schema.NotifierConfiguration{ + config := &schema.Notifier{ TemplatePath: string([]byte{0x0, 0x1}), } diff --git a/internal/configuration/validator/ntp_test.go b/internal/configuration/validator/ntp_test.go index 39ffe7907..9cb5611eb 100644 --- a/internal/configuration/validator/ntp_test.go +++ b/internal/configuration/validator/ntp_test.go @@ -11,7 +11,7 @@ import ( func newDefaultNTPConfig() schema.Configuration { return schema.Configuration{ - NTP: schema.NTPConfiguration{}, + NTP: schema.NTP{}, } } diff --git a/internal/configuration/validator/password_policy.go b/internal/configuration/validator/password_policy.go index 33e774fd2..07b0c773e 100644 --- a/internal/configuration/validator/password_policy.go +++ b/internal/configuration/validator/password_policy.go @@ -8,7 +8,7 @@ import ( ) // ValidatePasswordPolicy validates and updates the Password Policy configuration. -func ValidatePasswordPolicy(config *schema.PasswordPolicyConfiguration, validator *schema.StructValidator) { +func ValidatePasswordPolicy(config *schema.PasswordPolicy, validator *schema.StructValidator) { if !utils.IsBoolCountLessThanN(1, true, config.Standard.Enabled, config.ZXCVBN.Enabled) { validator.Push(fmt.Errorf(errPasswordPolicyMultipleDefined)) } diff --git a/internal/configuration/validator/password_policy_test.go b/internal/configuration/validator/password_policy_test.go index 5ce417c01..da3653679 100644 --- a/internal/configuration/validator/password_policy_test.go +++ b/internal/configuration/validator/password_policy_test.go @@ -13,26 +13,26 @@ import ( func TestValidatePasswordPolicy(t *testing.T) { testCases := []struct { desc string - have, expected *schema.PasswordPolicyConfiguration + have, expected *schema.PasswordPolicy expectedErrs []string }{ { desc: "ShouldRaiseErrorsWhenMisconfigured", - have: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + have: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: -1, }, - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, }, }, - expected: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + expected: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: -1, }, - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: 3, }, @@ -44,14 +44,14 @@ func TestValidatePasswordPolicy(t *testing.T) { }, { desc: "ShouldNotRaiseErrorsStandard", - have: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + have: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: 8, }, }, - expected: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + expected: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: 8, }, @@ -59,13 +59,13 @@ func TestValidatePasswordPolicy(t *testing.T) { }, { desc: "ShouldNotRaiseErrorsZXCVBN", - have: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + have: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, }, }, - expected: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + expected: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: 3, }, @@ -73,14 +73,14 @@ func TestValidatePasswordPolicy(t *testing.T) { }, { desc: "ShouldSetDefaultstandard", - have: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + have: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: 0, }, }, - expected: &schema.PasswordPolicyConfiguration{ - Standard: schema.PasswordPolicyStandardParams{ + expected: &schema.PasswordPolicy{ + Standard: schema.PasswordPolicyStandard{ Enabled: true, MinLength: 8, }, @@ -88,14 +88,14 @@ func TestValidatePasswordPolicy(t *testing.T) { }, { desc: "ShouldRaiseErrorsZXCVBNTooLow", - have: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + have: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: -1, }, }, - expected: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + expected: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: -1, }, @@ -106,14 +106,14 @@ func TestValidatePasswordPolicy(t *testing.T) { }, { desc: "ShouldRaiseErrorsZXCVBNTooHigh", - have: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + have: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: 5, }, }, - expected: &schema.PasswordPolicyConfiguration{ - ZXCVBN: schema.PasswordPolicyZXCVBNParams{ + expected: &schema.PasswordPolicy{ + ZXCVBN: schema.PasswordPolicyZXCVBN{ Enabled: true, MinScore: 5, }, diff --git a/internal/configuration/validator/regulation_test.go b/internal/configuration/validator/regulation_test.go index fd88a73f9..23df5d6d4 100644 --- a/internal/configuration/validator/regulation_test.go +++ b/internal/configuration/validator/regulation_test.go @@ -11,7 +11,7 @@ import ( func newDefaultRegulationConfig() schema.Configuration { config := schema.Configuration{ - Regulation: schema.RegulationConfiguration{}, + Regulation: schema.Regulation{}, } return config diff --git a/internal/configuration/validator/server.go b/internal/configuration/validator/server.go index a4f69cf46..2102763a9 100644 --- a/internal/configuration/validator/server.go +++ b/internal/configuration/validator/server.go @@ -182,7 +182,7 @@ func ValidateServerEndpoints(config *schema.Configuration, validator *schema.Str } } -func validateServerEndpointsAuthzEndpoint(config *schema.Configuration, name string, endpoint schema.ServerAuthzEndpoint, validator *schema.StructValidator) { +func validateServerEndpointsAuthzEndpoint(config *schema.Configuration, name string, endpoint schema.ServerEndpointsAuthz, validator *schema.StructValidator) { if name == legacy { switch endpoint.Implementation { case authzImplementationLegacy: @@ -207,7 +207,7 @@ func validateServerEndpointsAuthzEndpoint(config *schema.Configuration, name str } } -func validateServerEndpointsAuthzStrategies(name string, strategies []schema.ServerAuthzEndpointAuthnStrategy, validator *schema.StructValidator) { +func validateServerEndpointsAuthzStrategies(name string, strategies []schema.ServerEndpointsAuthzAuthnStrategy, validator *schema.StructValidator) { names := make([]string, len(strategies)) for _, strategy := range strategies { diff --git a/internal/configuration/validator/server_test.go b/internal/configuration/validator/server_test.go index 191411c1c..968b72e58 100644 --- a/internal/configuration/validator/server_test.go +++ b/internal/configuration/validator/server_test.go @@ -40,12 +40,12 @@ func TestShouldSetDefaultServerValues(t *testing.T) { func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { testCases := []struct { name string - have schema.ServerConfiguration + have schema.Server expected schema.Address }{ { "ShouldParseAll", - schema.ServerConfiguration{ + schema.Server{ Host: "abc", Port: 123, Path: "subpath", @@ -54,7 +54,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { }, { "ShouldParseHostAndPort", - schema.ServerConfiguration{ + schema.Server{ Host: "abc", Port: 123, }, @@ -62,7 +62,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { }, { "ShouldParseHostAndPath", - schema.ServerConfiguration{ + schema.Server{ Host: "abc", Path: "subpath", }, @@ -70,7 +70,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { }, { "ShouldParsePortAndPath", - schema.ServerConfiguration{ + schema.Server{ Port: 123, Path: "subpath", }, @@ -78,21 +78,21 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { }, { "ShouldParseHost", - schema.ServerConfiguration{ + schema.Server{ Host: "abc", }, MustParseAddress("tcp://abc:9091/"), }, { "ShouldParsePort", - schema.ServerConfiguration{ + schema.Server{ Port: 123, }, MustParseAddress("tcp://:123/"), }, { "ShouldParsePath", - schema.ServerConfiguration{ + schema.Server{ Path: "subpath", }, MustParseAddress("tcp://:9091/subpath"), @@ -131,7 +131,7 @@ func TestShouldSetDefaultConfig(t *testing.T) { func TestValidateSeverAddress(t *testing.T) { config := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: &schema.AddressTCP{Address: MustParseAddress("tcp://:9091/path/")}, }, } @@ -161,7 +161,7 @@ func TestValidateServerShouldCorrectlyIdentifyValidAddressSchemes(t *testing.T) } have := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Buffers: schema.ServerBuffers{ Read: -1, Write: -1, @@ -204,7 +204,7 @@ func TestValidateServerShouldCorrectlyIdentifyValidAddressSchemes(t *testing.T) func TestShouldDefaultOnNegativeValues(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Buffers: schema.ServerBuffers{ Read: -1, Write: -1, @@ -232,7 +232,7 @@ func TestShouldDefaultOnNegativeValues(t *testing.T) { func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Path: "app le", }, } @@ -247,7 +247,7 @@ func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) { func TestShouldRaiseOnForwardSlashInPath(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Path: "app/le", }, } @@ -420,7 +420,7 @@ func TestShouldNotUpdateConfig(t *testing.T) { func TestServerEndpointsDevelShouldWarn(t *testing.T) { config := &schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Endpoints: schema.ServerEndpoints{ EnablePprof: true, EnableExpvars: true, @@ -442,14 +442,14 @@ func TestServerEndpointsDevelShouldWarn(t *testing.T) { func TestServerAuthzEndpointErrors(t *testing.T) { testCases := []struct { name string - have map[string]schema.ServerAuthzEndpoint + have map[string]schema.ServerEndpointsAuthz errs []string }{ {"ShouldAllowDefaultEndpoints", schema.DefaultServerConfiguration.Endpoints.Authz, nil}, {"ShouldAllowSetDefaultEndpoints", nil, nil}, { "ShouldErrorOnInvalidEndpointImplementations", - map[string]schema.ServerAuthzEndpoint{ + map[string]schema.ServerEndpointsAuthz{ "example": {Implementation: "zero"}, }, []string{ @@ -458,7 +458,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) { }, { "ShouldErrorOnInvalidEndpointImplementationLegacy", - map[string]schema.ServerAuthzEndpoint{ + map[string]schema.ServerEndpointsAuthz{ "legacy": {Implementation: "zero"}, }, []string{ @@ -467,15 +467,15 @@ func TestServerAuthzEndpointErrors(t *testing.T) { }, { "ShouldErrorOnInvalidEndpointLegacyImplementation", - map[string]schema.ServerAuthzEndpoint{ + map[string]schema.ServerEndpointsAuthz{ "legacy": {Implementation: "ExtAuthz"}, }, []string{"server: endpoints: authz: legacy: option 'implementation' is invalid: the endpoint with the name 'legacy' must use the 'Legacy' implementation"}, }, { "ShouldErrorOnInvalidAuthnStrategies", - map[string]schema.ServerAuthzEndpoint{ - "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{{Name: "bad-name"}}}, + map[string]schema.ServerEndpointsAuthz{ + "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{{Name: "bad-name"}}}, }, []string{ "server: endpoints: authz: example: authn_strategies: option 'name' must be one of 'CookieSession', 'HeaderAuthorization', 'HeaderProxyAuthorization', 'HeaderAuthRequestProxyAuthorization', or 'HeaderLegacy' but it's configured as 'bad-name'", @@ -483,14 +483,14 @@ func TestServerAuthzEndpointErrors(t *testing.T) { }, { "ShouldErrorOnDuplicateName", - map[string]schema.ServerAuthzEndpoint{ - "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{{Name: "CookieSession"}, {Name: "CookieSession"}}}, + map[string]schema.ServerEndpointsAuthz{ + "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{{Name: "CookieSession"}, {Name: "CookieSession"}}}, }, []string{"server: endpoints: authz: example: authn_strategies: duplicate strategy name detected with name 'CookieSession'"}, }, { "ShouldErrorOnInvalidChars", - map[string]schema.ServerAuthzEndpoint{ + map[string]schema.ServerEndpointsAuthz{ "/abc": {Implementation: "ForwardAuth"}, "/abc/": {Implementation: "ForwardAuth"}, "abc/": {Implementation: "ForwardAuth"}, @@ -515,7 +515,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) { }, { "ShouldErrorOnEndpointsWithDuplicatePrefix", - map[string]schema.ServerAuthzEndpoint{ + map[string]schema.ServerEndpointsAuthz{ "apple": {Implementation: "ForwardAuth"}, "apple/abc": {Implementation: "ForwardAuth"}, "pear/abc": {Implementation: "ExtAuthz"}, @@ -568,7 +568,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) { } func TestServerAuthzEndpointLegacyAsImplementationLegacyWhenBlank(t *testing.T) { - have := map[string]schema.ServerAuthzEndpoint{ + have := map[string]schema.ServerEndpointsAuthz{ "legacy": {}, } diff --git a/internal/configuration/validator/session.go b/internal/configuration/validator/session.go index 1de078ef8..6104008ab 100644 --- a/internal/configuration/validator/session.go +++ b/internal/configuration/validator/session.go @@ -10,7 +10,7 @@ import ( ) // ValidateSession validates and update session configuration. -func ValidateSession(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func ValidateSession(config *schema.Session, validator *schema.StructValidator) { if config.Name == "" { config.Name = schema.DefaultSessionConfiguration.Name } @@ -26,7 +26,7 @@ func ValidateSession(config *schema.SessionConfiguration, validator *schema.Stru validateSession(config, validator) } -func validateSession(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateSession(config *schema.Session, validator *schema.StructValidator) { if config.Expiration <= 0 { config.Expiration = schema.DefaultSessionConfiguration.Expiration // 1 hour. } @@ -51,27 +51,27 @@ func validateSession(config *schema.SessionConfiguration, validator *schema.Stru cookies := len(config.Cookies) switch { - case cookies == 0 && config.Domain != "": + case cookies == 0 && config.Domain != "": //nolint:staticcheck // Add legacy configuration to the domains list. - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + config.Cookies = append(config.Cookies, schema.SessionCookie{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: config.Name, - Domain: config.Domain, SameSite: config.SameSite, Expiration: config.Expiration, Inactivity: config.Inactivity, RememberMe: config.RememberMe, DisableRememberMe: config.DisableRememberMe, }, + Domain: config.Domain, //nolint:staticcheck }) - case cookies != 0 && config.Domain != "": + case cookies != 0 && config.Domain != "": //nolint:staticcheck validator.Push(fmt.Errorf(errFmtSessionLegacyAndWarning)) } validateSessionCookieDomains(config, validator) } -func validateSessionCookieDomains(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateSessionCookieDomains(config *schema.Session, validator *schema.StructValidator) { if len(config.Cookies) == 0 { validator.Push(fmt.Errorf(errFmtSessionOptionRequired, "cookies")) } @@ -85,7 +85,7 @@ func validateSessionCookieDomains(config *schema.SessionConfiguration, validator validateSessionCookieName(i, config) - validateSessionSafeRedirection(i, config, validator) + validateSessionCookiesAutheliaURL(i, config, validator) validateSessionExpiration(i, config) @@ -98,7 +98,7 @@ func validateSessionCookieDomains(config *schema.SessionConfiguration, validator } // validateSessionDomainName returns error if the domain name is invalid. -func validateSessionDomainName(i int, config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateSessionDomainName(i int, config *schema.Session, validator *schema.StructValidator) { var d = config.Cookies[i] switch { @@ -123,13 +123,13 @@ func validateSessionDomainName(i int, config *schema.SessionConfiguration, valid } } -func validateSessionCookieName(i int, config *schema.SessionConfiguration) { +func validateSessionCookieName(i int, config *schema.Session) { if config.Cookies[i].Name == "" { config.Cookies[i].Name = config.Name } } -func validateSessionExpiration(i int, config *schema.SessionConfiguration) { +func validateSessionExpiration(i int, config *schema.Session) { if config.Cookies[i].Expiration <= 0 { config.Cookies[i].Expiration = config.Expiration } @@ -140,7 +140,7 @@ func validateSessionExpiration(i int, config *schema.SessionConfiguration) { } // validateSessionUniqueCookieDomain Check the current domains do not share a root domain with previous domains. -func validateSessionUniqueCookieDomain(i int, config *schema.SessionConfiguration, domains []string, validator *schema.StructValidator) { +func validateSessionUniqueCookieDomain(i int, config *schema.Session, domains []string, validator *schema.StructValidator) { var d = config.Cookies[i] if utils.IsStringInSliceF(d.Domain, domains, utils.HasDomainSuffix) { if utils.IsStringInSlice(d.Domain, domains) { @@ -151,8 +151,8 @@ func validateSessionUniqueCookieDomain(i int, config *schema.SessionConfiguratio } } -// validateSessionSafeRedirection validates that AutheliaURL is safe for redirection. -func validateSessionSafeRedirection(index int, config *schema.SessionConfiguration, validator *schema.StructValidator) { +// validateSessionCookiesAutheliaURL validates the AutheliaURL. +func validateSessionCookiesAutheliaURL(index int, config *schema.Session, validator *schema.StructValidator) { var d = config.Cookies[index] if d.AutheliaURL != nil && d.Domain != "" && !utils.IsURISafeRedirection(d.AutheliaURL, d.Domain) { @@ -164,7 +164,7 @@ func validateSessionSafeRedirection(index int, config *schema.SessionConfigurati } } -func validateSessionRememberMe(i int, config *schema.SessionConfiguration) { +func validateSessionRememberMe(i int, config *schema.Session) { if config.Cookies[i].RememberMe <= 0 && config.Cookies[i].RememberMe != schema.RememberMeDisabled { config.Cookies[i].RememberMe = config.RememberMe } @@ -174,7 +174,7 @@ func validateSessionRememberMe(i int, config *schema.SessionConfiguration) { } } -func validateSessionSameSite(i int, config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateSessionSameSite(i int, config *schema.Session, validator *schema.StructValidator) { if config.Cookies[i].SameSite == "" { if utils.IsStringInSlice(config.SameSite, validSessionSameSiteValues) { config.Cookies[i].SameSite = config.SameSite @@ -186,17 +186,17 @@ func validateSessionSameSite(i int, config *schema.SessionConfiguration, validat } } -func sessionDomainDescriptor(position int, domain schema.SessionCookieConfiguration) string { +func sessionDomainDescriptor(position int, domain schema.SessionCookie) string { return fmt.Sprintf("#%d (domain '%s')", position+1, domain.Domain) } -func validateRedisCommon(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateRedisCommon(config *schema.Session, validator *schema.StructValidator) { if config.Secret == "" { validator.Push(fmt.Errorf(errFmtSessionSecretRequired, "redis")) } if config.Redis.TLS != nil { - configDefaultTLS := &schema.TLSConfig{ + configDefaultTLS := &schema.TLS{ ServerName: config.Redis.Host, MinimumVersion: schema.DefaultRedisConfiguration.TLS.MinimumVersion, MaximumVersion: schema.DefaultRedisConfiguration.TLS.MaximumVersion, @@ -208,7 +208,7 @@ func validateRedisCommon(config *schema.SessionConfiguration, validator *schema. } } -func validateRedis(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateRedis(config *schema.Session, validator *schema.StructValidator) { if config.Redis.Host == "" { validator.Push(fmt.Errorf(errFmtSessionRedisHostRequired)) } @@ -220,11 +220,11 @@ func validateRedis(config *schema.SessionConfiguration, validator *schema.Struct } if config.Redis.MaximumActiveConnections <= 0 { - config.Redis.MaximumActiveConnections = 8 + config.Redis.MaximumActiveConnections = schema.DefaultRedisConfiguration.MaximumActiveConnections } } -func validateRedisSentinel(config *schema.SessionConfiguration, validator *schema.StructValidator) { +func validateRedisSentinel(config *schema.Session, validator *schema.StructValidator) { if config.Redis.HighAvailability.SentinelName == "" { validator.Push(fmt.Errorf(errFmtSessionRedisSentinelMissingName)) } diff --git a/internal/configuration/validator/session_test.go b/internal/configuration/validator/session_test.go index 1f18eaea4..a55774829 100644 --- a/internal/configuration/validator/session_test.go +++ b/internal/configuration/validator/session_test.go @@ -13,11 +13,11 @@ import ( "github.com/authelia/authelia/v4/internal/configuration/schema" ) -func newDefaultSessionConfig() schema.SessionConfiguration { - config := schema.SessionConfiguration{} +func newDefaultSessionConfig() schema.Session { + config := schema.Session{} config.Secret = testJWTSecret - config.Domain = exampleDotCom - config.Cookies = []schema.SessionCookieConfiguration{} + config.Domain = exampleDotCom //nolint:staticcheck + config.Cookies = []schema.SessionCookie{} return config } @@ -40,27 +40,30 @@ func TestShouldSetDefaultSessionValues(t *testing.T) { func TestShouldSetDefaultSessionDomainsValues(t *testing.T) { testCases := []struct { name string - have schema.SessionConfiguration - expected schema.SessionConfiguration + have schema.Session + expected schema.Session errs []string }{ { "ShouldSetGoodDefaultValues", - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ + SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, + Domain: exampleDotCom, }, - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, - Cookies: []schema.SessionCookieConfiguration{ + Domain: exampleDotCom, + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, + Domain: exampleDotCom, }, }, }, @@ -68,29 +71,31 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) { }, { "ShouldNotSetBadDefaultValues", - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ SameSite: "BAD VALUE", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, - Cookies: []schema.SessionCookieConfiguration{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", Domain: exampleDotCom, + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, + Domain: exampleDotCom, }, }, }, - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "authelia_session", SameSite: "BAD VALUE", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, - Cookies: []schema.SessionCookieConfiguration{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", Domain: exampleDotCom, SameSite: schema.DefaultSessionConfiguration.SameSite, + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", SameSite: schema.DefaultSessionConfiguration.SameSite, Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, }, + Domain: exampleDotCom, }, }, }, @@ -100,41 +105,42 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) { }, { "ShouldSetDefaultValuesForEachConfig", - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, }, - Cookies: []schema.SessionCookieConfiguration{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: exampleDotCom, - }, + Domain: exampleDotCom, }, { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "example2.com", Name: "authelia_session", SameSite: "strict", + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", SameSite: "strict", }, + Domain: "example2.com", }, }, }, - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, }, - Cookies: []schema.SessionCookieConfiguration{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "default_session", Domain: exampleDotCom, SameSite: "lax", + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, }, + Domain: exampleDotCom, }, { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", Domain: "example2.com", SameSite: "strict", + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", SameSite: "strict", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, }, + Domain: "example2.com", }, }, }, @@ -142,17 +148,18 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) { }, { "ShouldErrorOnEmptyConfig", - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "", SameSite: "", Domain: "", + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "", SameSite: "", }, - Cookies: []schema.SessionCookieConfiguration{}, + Domain: "", + Cookies: []schema.SessionCookie{}, }, - schema.SessionConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + schema.Session{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "authelia_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute * 5, RememberMe: time.Hour * 24 * 30, }, - Cookies: []schema.SessionCookieConfiguration{}, + Cookies: []schema.SessionCookie{}, }, []string{ "session: option 'cookies' is required", @@ -203,7 +210,7 @@ func TestShouldWarnSessionValuesWhenPotentiallyInvalid(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Domain = ".example.com" + config.Domain = ".example.com" //nolint:staticcheck ValidateSession(&config, validator) @@ -225,7 +232,7 @@ func TestShouldHandleRedisConfigSuccessfully(t *testing.T) { config = newDefaultSessionConfig() // Set redis config because password must be set only when redis is used. - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.localhost", Port: 6379, Password: "password", @@ -243,7 +250,7 @@ func TestShouldRaiseErrorWithInvalidRedisPortLow(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "authelia-port-1", Port: -1, } @@ -260,7 +267,7 @@ func TestShouldRaiseErrorWithInvalidRedisPortHigh(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "authelia-port-1", Port: 65536, } @@ -287,7 +294,7 @@ func TestShouldRaiseErrorWhenRedisIsUsedAndSecretNotSet(t *testing.T) { config.Secret = "" // Set redis config because password must be set only when redis is used. - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.localhost", Port: 6379, } @@ -311,7 +318,7 @@ func TestShouldRaiseErrorWhenRedisHasHostnameButNoPort(t *testing.T) { config = newDefaultSessionConfig() // Set redis config because password must be set only when redis is used. - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.localhost", Port: 0, } @@ -327,13 +334,13 @@ func TestShouldRaiseOneErrorWhenRedisHighAvailabilityHasNodesWithNoHost(t *testi validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis", Port: 6379, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "authelia-sentinel", SentinelPassword: "abc123", - Nodes: []schema.RedisNode{ + Nodes: []schema.SessionRedisHighAvailabilityNode{ { Port: 26379, }, @@ -358,10 +365,10 @@ func TestShouldRaiseOneErrorWhenRedisHighAvailabilityDoesNotHaveSentinelName(t * validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis", Port: 6379, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelPassword: "abc123", }, } @@ -380,13 +387,13 @@ func TestShouldUpdateDefaultPortWhenRedisSentinelHasNodes(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis", Port: 6379, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "authelia-sentinel", SentinelPassword: "abc123", - Nodes: []schema.RedisNode{ + Nodes: []schema.SessionRedisHighAvailabilityNode{ { Host: "node-1", Port: 333, @@ -416,12 +423,12 @@ func TestShouldRaiseErrorsWhenRedisSentinelOptionsIncorrectlyConfigured(t *testi config := newDefaultSessionConfig() config.Secret = "" - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Port: 65536, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "sentinel", SentinelPassword: "abc123", - Nodes: []schema.RedisNode{ + Nodes: []schema.SessionRedisHighAvailabilityNode{ { Host: "node1", Port: 26379, @@ -447,12 +454,12 @@ func TestShouldRaiseErrorsWhenRedisSentinelOptionsIncorrectlyConfigured(t *testi config = newDefaultSessionConfig() config.Secret = "" - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Port: -1, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "sentinel", SentinelPassword: "abc123", - Nodes: []schema.RedisNode{ + Nodes: []schema.SessionRedisHighAvailabilityNode{ { Host: "node1", Port: 26379, @@ -478,13 +485,13 @@ func TestShouldNotRaiseErrorsAndSetDefaultPortWhenRedisSentinelPortBlank(t *test validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "mysentinelHost", Port: 0, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "sentinel", SentinelPassword: "abc123", - Nodes: []schema.RedisNode{ + Nodes: []schema.SessionRedisHighAvailabilityNode{ { Host: "node1", Port: 26379, @@ -507,9 +514,9 @@ func TestShouldRaiseErrorWhenRedisHostAndHighAvailabilityNodesEmpty(t *testing.T validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Port: 26379, - HighAvailability: &schema.RedisHighAvailabilityConfiguration{ + HighAvailability: &schema.SessionRedisHighAvailability{ SentinelName: "sentinel", SentinelPassword: "abc123", RouteByLatency: true, @@ -529,7 +536,7 @@ func TestShouldRaiseErrorsWhenRedisHostNotSet(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Port: 6379, } @@ -547,10 +554,10 @@ func TestShouldSetDefaultRedisTLSOptions(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.local", Port: 6379, - TLS: &schema.TLSConfig{}, + TLS: &schema.TLS{}, } ValidateSession(&config, validator) @@ -567,10 +574,10 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsSSL30(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.local", Port: 6379, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck }, } @@ -587,10 +594,10 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T) validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Redis = &schema.RedisSessionConfiguration{ + config.Redis = &schema.SessionRedis{ Host: "redis.local", Port: 6379, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10}, }, @@ -607,40 +614,32 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T) func TestShouldRaiseErrorWhenHaveDuplicatedDomainName(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Domain = "" - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: exampleDotCom, - }, + config.Domain = "" //nolint:staticcheck + config.Cookies = append(config.Cookies, schema.SessionCookie{ + Domain: exampleDotCom, AutheliaURL: MustParseURL("https://login.example.com"), }) - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: exampleDotCom, - }, + config.Cookies = append(config.Cookies, schema.SessionCookie{ + Domain: exampleDotCom, AutheliaURL: MustParseURL("https://login.example.com"), }) ValidateSession(&config, validator) assert.False(t, validator.HasWarnings()) assert.Len(t, validator.Errors(), 1) - assert.EqualError(t, validator.Errors()[0], fmt.Sprintf(errFmtSessionDomainDuplicate, sessionDomainDescriptor(1, schema.SessionCookieConfiguration{SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{Domain: exampleDotCom}}))) + assert.EqualError(t, validator.Errors()[0], fmt.Sprintf(errFmtSessionDomainDuplicate, sessionDomainDescriptor(1, schema.SessionCookie{Domain: exampleDotCom}))) } func TestShouldRaiseErrorWhenSubdomainConflicts(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Domain = "" - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: exampleDotCom, - }, + config.Domain = "" //nolint:staticcheck + config.Cookies = append(config.Cookies, schema.SessionCookie{ + Domain: exampleDotCom, AutheliaURL: MustParseURL("https://login.example.com"), }) - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "internal.example.com", - }, + config.Cookies = append(config.Cookies, schema.SessionCookie{ + Domain: "internal.example.com", AutheliaURL: MustParseURL("https://login.internal.example.com"), }) @@ -672,13 +671,11 @@ func TestShouldRaiseErrorWhenDomainIsInvalid(t *testing.T) { t.Run(tc.name, func(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Domain = "" + config.Domain = "" //nolint:staticcheck - config.Cookies = []schema.SessionCookieConfiguration{ + config.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: tc.have, - }, + Domain: tc.have, }, } @@ -712,13 +709,13 @@ func TestShouldRaiseErrorWhenPortalURLIsInvalid(t *testing.T) { t.Run(tc.name, func(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Domain = "" - config.Cookies = []schema.SessionCookieConfiguration{ + config.Domain = "" //nolint:staticcheck + config.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Name: "authelia_session", - Domain: exampleDotCom, + SessionCookieCommon: schema.SessionCookieCommon{ + Name: "authelia_session", }, + Domain: exampleDotCom, AutheliaURL: MustParseURL(tc.have)}, } @@ -751,7 +748,7 @@ func TestShouldRaiseErrorWhenSameSiteSetIncorrectly(t *testing.T) { func TestShouldNotRaiseErrorWhenSameSiteSetCorrectly(t *testing.T) { validator := schema.NewStructValidator() - var config schema.SessionConfiguration + var config schema.Session validOptions := []string{"none", "lax", "strict"} @@ -802,15 +799,15 @@ func TestShouldNotAllowLegacyAndModernCookiesConfig(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() - config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + config.Cookies = append(config.Cookies, schema.SessionCookie{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: config.Name, - Domain: config.Domain, SameSite: config.SameSite, Expiration: config.Expiration, Inactivity: config.Inactivity, RememberMe: config.RememberMe, }, + Domain: config.Domain, //nolint:staticcheck }) ValidateSession(&config, validator) diff --git a/internal/configuration/validator/shared.go b/internal/configuration/validator/shared.go index 297ba0c2b..919f4bf3a 100644 --- a/internal/configuration/validator/shared.go +++ b/internal/configuration/validator/shared.go @@ -8,8 +8,8 @@ import ( "github.com/authelia/authelia/v4/internal/configuration/schema" ) -// ValidateTLSConfig sets the default values and validates a schema.TLSConfig. -func ValidateTLSConfig(config *schema.TLSConfig, configDefault *schema.TLSConfig) (err error) { +// ValidateTLSConfig sets the default values and validates a schema.TLS. +func ValidateTLSConfig(config *schema.TLS, configDefault *schema.TLS) (err error) { if configDefault == nil { return errors.New("must provide configDefault") } diff --git a/internal/configuration/validator/shared_test.go b/internal/configuration/validator/shared_test.go index 27e48ad75..fe0d3347d 100644 --- a/internal/configuration/validator/shared_test.go +++ b/internal/configuration/validator/shared_test.go @@ -10,16 +10,16 @@ import ( func TestValidateTLSConfig(t *testing.T) { var ( - config, configDefault *schema.TLSConfig + config, configDefault *schema.TLS ) assert.EqualError(t, ValidateTLSConfig(config, configDefault), "must provide configDefault") - configDefault = &schema.TLSConfig{} + configDefault = &schema.TLS{} assert.NoError(t, ValidateTLSConfig(config, configDefault)) - config = &schema.TLSConfig{} + config = &schema.TLS{} assert.NoError(t, ValidateTLSConfig(config, configDefault)) diff --git a/internal/configuration/validator/storage.go b/internal/configuration/validator/storage.go index 0f6f1dad6..76082b07e 100644 --- a/internal/configuration/validator/storage.go +++ b/internal/configuration/validator/storage.go @@ -9,7 +9,7 @@ import ( ) // ValidateStorage validates storage configuration. -func ValidateStorage(config schema.StorageConfiguration, validator *schema.StructValidator) { +func ValidateStorage(config schema.Storage, validator *schema.StructValidator) { if config.Local == nil && config.MySQL == nil && config.PostgreSQL == nil { validator.Push(errors.New(errStrStorage)) } @@ -30,7 +30,7 @@ func ValidateStorage(config schema.StorageConfiguration, validator *schema.Struc } } -func validateSQLConfiguration(config *schema.SQLStorageConfiguration, validator *schema.StructValidator, provider string) { +func validateSQLConfiguration(config *schema.StorageSQL, validator *schema.StructValidator, provider string) { if config.Address == nil { if config.Host == "" { //nolint:staticcheck validator.Push(fmt.Errorf(errFmtStorageOptionMustBeProvided, provider, "address")) @@ -69,11 +69,11 @@ func validateSQLConfiguration(config *schema.SQLStorageConfiguration, validator } } -func validateMySQLConfiguration(config *schema.MySQLStorageConfiguration, validator *schema.StructValidator) { - validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "mysql") +func validateMySQLConfiguration(config *schema.StorageMySQL, validator *schema.StructValidator) { + validateSQLConfiguration(&config.StorageSQL, validator, "mysql") if config.TLS != nil { - configDefaultTLS := &schema.TLSConfig{ + configDefaultTLS := &schema.TLS{ MinimumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MinimumVersion, MaximumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MaximumVersion, } @@ -88,18 +88,18 @@ func validateMySQLConfiguration(config *schema.MySQLStorageConfiguration, valida } } -func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfiguration, validator *schema.StructValidator) { - validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "postgres") +func validatePostgreSQLConfiguration(config *schema.StoragePostgreSQL, validator *schema.StructValidator) { + validateSQLConfiguration(&config.StorageSQL, validator, "postgres") if config.Schema == "" { config.Schema = schema.DefaultPostgreSQLStorageConfiguration.Schema } switch { - case config.TLS != nil && config.SSL != nil: + case config.TLS != nil && config.SSL != nil: //nolint:staticcheck validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLAndTLSConfig)) case config.TLS != nil: - configDefaultTLS := &schema.TLSConfig{ + configDefaultTLS := &schema.TLS{ ServerName: config.Address.Hostname(), MinimumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MinimumVersion, MaximumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MaximumVersion, @@ -108,19 +108,19 @@ func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfigurati if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil { validator.Push(fmt.Errorf(errFmtStorageTLSConfigInvalid, "postgres", err)) } - case config.SSL != nil: + case config.SSL != nil: //nolint:staticcheck validator.PushWarning(fmt.Errorf(warnFmtStoragePostgreSQLInvalidSSLDeprecated)) switch { - case config.SSL.Mode == "": - config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode - case !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes): - validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLMode, strJoinOr(validStoragePostgreSQLSSLModes), config.SSL.Mode)) + case config.SSL.Mode == "": //nolint:staticcheck + config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode //nolint:staticcheck + case !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes): //nolint:staticcheck + validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLMode, strJoinOr(validStoragePostgreSQLSSLModes), config.SSL.Mode)) //nolint:staticcheck } } } -func validateLocalStorageConfiguration(config *schema.LocalStorageConfiguration, validator *schema.StructValidator) { +func validateLocalStorageConfiguration(config *schema.StorageLocal, validator *schema.StructValidator) { if config.Path == "" { validator.Push(fmt.Errorf(errFmtStorageOptionMustBeProvided, "local", "path")) } diff --git a/internal/configuration/validator/storage_test.go b/internal/configuration/validator/storage_test.go index 1001add41..f8b45482b 100644 --- a/internal/configuration/validator/storage_test.go +++ b/internal/configuration/validator/storage_test.go @@ -11,7 +11,7 @@ import ( type StorageSuite struct { suite.Suite - config schema.StorageConfiguration + config schema.Storage validator *schema.StructValidator } @@ -36,7 +36,7 @@ func (suite *StorageSuite) TestShouldValidateOneStorageIsConfigured() { } func (suite *StorageSuite) TestShouldValidateLocalPathIsProvided() { - suite.config.Local = &schema.LocalStorageConfiguration{ + suite.config.Local = &schema.StorageLocal{ Path: "", } @@ -57,7 +57,7 @@ func (suite *StorageSuite) TestShouldValidateLocalPathIsProvided() { } func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabaseAreProvided() { - suite.config.MySQL = &schema.MySQLStorageConfiguration{} + suite.config.MySQL = &schema.StorageMySQL{} ValidateStorage(suite.config, suite.validator) suite.Require().Len(suite.validator.Errors(), 3) @@ -66,8 +66,8 @@ func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabas suite.Assert().EqualError(suite.validator.Errors()[2], "storage: mysql: option 'database' is required") suite.validator.Clear() - suite.config.MySQL = &schema.MySQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.MySQL = &schema.StorageMySQL{ + StorageSQL: schema.StorageSQL{ Host: "localhost", Username: "myuser", Password: "pass", @@ -81,14 +81,14 @@ func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabas } func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() { - suite.config.MySQL = &schema.MySQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.MySQL = &schema.StorageMySQL{ + StorageSQL: schema.StorageSQL{ Address: &schema.AddressTCP{Address: MustParseAddress("tcp://mysql:1234")}, Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, }, } @@ -103,14 +103,14 @@ func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() { } func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() { - suite.config.MySQL = &schema.MySQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.MySQL = &schema.StorageMySQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck }, } @@ -124,14 +124,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() { } func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreaterThanMaximum() { - suite.config.MySQL = &schema.MySQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.MySQL = &schema.StorageMySQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, }, @@ -146,7 +146,7 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreate } func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDatabaseAreProvided() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{} + suite.config.PostgreSQL = &schema.StoragePostgreSQL{} suite.config.MySQL = nil ValidateStorage(suite.config, suite.validator) @@ -156,8 +156,8 @@ func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDa suite.Assert().EqualError(suite.validator.Errors()[2], "storage: postgres: option 'database' is required") suite.validator.Clear() - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "postgre", Username: "myuser", Password: "pass", @@ -171,8 +171,8 @@ func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDa } func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", @@ -185,21 +185,21 @@ func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() { suite.Assert().Len(suite.validator.Warnings(), 0) suite.Assert().Len(suite.validator.Errors(), 0) - suite.Assert().Nil(suite.config.PostgreSQL.SSL) + suite.Assert().Nil(suite.config.PostgreSQL.SSL) //nolint:staticcheck suite.Assert().Nil(suite.config.PostgreSQL.TLS) suite.Assert().Equal("public", suite.config.PostgreSQL.Schema) } func (suite *StorageSuite) TestShouldValidatePostgresTLSDefaults() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{}, + TLS: &schema.TLS{}, } ValidateStorage(suite.config, suite.validator) @@ -207,21 +207,21 @@ func (suite *StorageSuite) TestShouldValidatePostgresTLSDefaults() { suite.Assert().Len(suite.validator.Warnings(), 0) suite.Assert().Len(suite.validator.Errors(), 0) - suite.Assert().Nil(suite.config.PostgreSQL.SSL) + suite.Assert().Nil(suite.config.PostgreSQL.SSL) //nolint:staticcheck suite.Require().NotNil(suite.config.PostgreSQL.TLS) suite.Assert().Equal(uint16(tls.VersionTLS12), suite.config.PostgreSQL.TLS.MinimumVersion.Value) } func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "mysql1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, }, } @@ -235,14 +235,14 @@ func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() { } func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck }, } @@ -256,14 +256,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() { } func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGreaterThanMaximum() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - TLS: &schema.TLSConfig{ + TLS: &schema.TLS{ MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, }, @@ -278,14 +278,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGrea } func (suite *StorageSuite) TestShouldValidatePostgresSSLDefaults() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - SSL: &schema.PostgreSQLSSLStorageConfiguration{}, + SSL: &schema.StoragePostgreSQLSSL{}, } ValidateStorage(suite.config, suite.validator) @@ -293,22 +293,22 @@ func (suite *StorageSuite) TestShouldValidatePostgresSSLDefaults() { suite.Assert().Len(suite.validator.Warnings(), 1) suite.Assert().Len(suite.validator.Errors(), 0) - suite.Assert().NotNil(suite.config.PostgreSQL.SSL) + suite.Assert().NotNil(suite.config.PostgreSQL.SSL) //nolint:staticcheck suite.Require().Nil(suite.config.PostgreSQL.TLS) - suite.Assert().Equal(schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode, suite.config.PostgreSQL.SSL.Mode) + suite.Assert().Equal(schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode, suite.config.PostgreSQL.SSL.Mode) //nolint:staticcheck } func (suite *StorageSuite) TestShouldRaiseErrorOnTLSAndLegacySSL() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, - SSL: &schema.PostgreSQLSSLStorageConfiguration{}, - TLS: &schema.TLSConfig{}, + SSL: &schema.StoragePostgreSQLSSL{}, + TLS: &schema.TLS{}, } ValidateStorage(suite.config, suite.validator) @@ -320,15 +320,15 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnTLSAndLegacySSL() { } func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfiguration() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db1", Username: "myuser", Password: "pass", Database: "database", }, Schema: "authelia", - SSL: &schema.PostgreSQLSSLStorageConfiguration{ + SSL: &schema.StoragePostgreSQLSSL{ Mode: "require", }, } @@ -338,21 +338,21 @@ func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfigu suite.Require().Len(suite.validator.Warnings(), 1) suite.Assert().Len(suite.validator.Errors(), 0) - suite.Assert().Equal("require", suite.config.PostgreSQL.SSL.Mode) + suite.Assert().Equal("require", suite.config.PostgreSQL.SSL.Mode) //nolint:staticcheck suite.Assert().Equal("authelia", suite.config.PostgreSQL.Schema) suite.Assert().EqualError(suite.validator.Warnings()[0], "storage: postgres: ssl: the ssl configuration options are deprecated and we recommend the tls options instead") } func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() { - suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ - SQLStorageConfiguration: schema.SQLStorageConfiguration{ + suite.config.PostgreSQL = &schema.StoragePostgreSQL{ + StorageSQL: schema.StorageSQL{ Host: "db2", Username: "myuser", Password: "pass", Database: "database", }, - SSL: &schema.PostgreSQLSSLStorageConfiguration{ + SSL: &schema.StoragePostgreSQLSSL{ Mode: "unknown", }, } @@ -366,7 +366,7 @@ func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() { func (suite *StorageSuite) TestShouldRaiseErrorOnNoEncryptionKey() { suite.config.EncryptionKey = "" - suite.config.Local = &schema.LocalStorageConfiguration{ + suite.config.Local = &schema.StorageLocal{ Path: "/this/is/a/path", } @@ -379,7 +379,7 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnNoEncryptionKey() { func (suite *StorageSuite) TestShouldRaiseErrorOnShortEncryptionKey() { suite.config.EncryptionKey = "abc" - suite.config.Local = &schema.LocalStorageConfiguration{ + suite.config.Local = &schema.StorageLocal{ Path: "/this/is/a/path", } diff --git a/internal/configuration/validator/telemetry_test.go b/internal/configuration/validator/telemetry_test.go index 59bbd7513..5e4e832ed 100644 --- a/internal/configuration/validator/telemetry_test.go +++ b/internal/configuration/validator/telemetry_test.go @@ -35,9 +35,9 @@ func TestValidateTelemetry(t *testing.T) { }, { "ShouldSetDefaultPort", - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://0.0.0.0")}}}, - &schema.Configuration{Telemetry: schema.TelemetryConfig{ - Metrics: schema.TelemetryMetricsConfig{ + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("tcp://0.0.0.0")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{ + Metrics: schema.TelemetryMetrics{ Address: mustParseAddress("tcp://0.0.0.0:9959/metrics"), Buffers: schema.ServerBuffers{ Read: 4096, @@ -55,22 +55,22 @@ func TestValidateTelemetry(t *testing.T) { }, { "ShouldSetDefaultPortAlt", - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://:0/metrics")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("tcp://:0/metrics")}}}, &schema.Configuration{Telemetry: schema.DefaultTelemetryConfig}, nil, nil, }, { "ShouldSetDefaultPortWithCustomIP", - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1")}}}, - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1:9959/metrics")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("tcp://127.0.0.1")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("tcp://127.0.0.1:9959/metrics")}}}, nil, nil, }, { "ShouldNotValidateUDP", - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0")}}}, - &schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0:9959/metrics")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("udp://0.0.0.0")}}}, + &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("udp://0.0.0.0:9959/metrics")}}}, nil, []string{"telemetry: metrics: option 'address' with value 'udp://0.0.0.0:0' is invalid: scheme must be one of 'tcp', 'tcp4', 'tcp6', or 'unix' but is configured as 'udp'"}, }, diff --git a/internal/configuration/validator/totp_test.go b/internal/configuration/validator/totp_test.go index b94f7f00b..bc3653fdf 100644 --- a/internal/configuration/validator/totp_test.go +++ b/internal/configuration/validator/totp_test.go @@ -13,8 +13,8 @@ import ( func TestValidateTOTP(t *testing.T) { testCases := []struct { desc string - have schema.TOTPConfiguration - expected schema.TOTPConfiguration + have schema.TOTP + expected schema.TOTP errs []string warns []string }{ @@ -24,12 +24,12 @@ func TestValidateTOTP(t *testing.T) { }, { desc: "ShouldNotSetDefaultTOTPValuesWhenDisabled", - have: schema.TOTPConfiguration{Disable: true}, - expected: schema.TOTPConfiguration{Disable: true}, + have: schema.TOTP{Disable: true}, + expected: schema.TOTP{Disable: true}, }, { desc: "ShouldNormalizeTOTPAlgorithm", - have: schema.TOTPConfiguration{ + have: schema.TOTP{ Algorithm: digestSHA1, Digits: 6, Period: 30, @@ -37,7 +37,7 @@ func TestValidateTOTP(t *testing.T) { Skew: schema.DefaultTOTPConfiguration.Skew, Issuer: "abc", }, - expected: schema.TOTPConfiguration{ + expected: schema.TOTP{ Algorithm: "SHA1", Digits: 6, Period: 30, @@ -48,7 +48,7 @@ func TestValidateTOTP(t *testing.T) { }, { desc: "ShouldRaiseErrorWhenInvalidTOTPAlgorithm", - have: schema.TOTPConfiguration{ + have: schema.TOTP{ Algorithm: "sha3", Digits: 6, Period: 30, @@ -62,7 +62,7 @@ func TestValidateTOTP(t *testing.T) { }, { desc: "ShouldRaiseErrorWhenInvalidTOTPValue", - have: schema.TOTPConfiguration{ + have: schema.TOTP{ Algorithm: "sha3", Period: 5, Digits: 20, diff --git a/internal/configuration/validator/util.go b/internal/configuration/validator/util.go index 037e58d0e..f5c7e49a2 100644 --- a/internal/configuration/validator/util.go +++ b/internal/configuration/validator/util.go @@ -190,7 +190,7 @@ func jwkCalculateThumbprint(key schema.CryptographicKey) (thumbprintStr string, return fmt.Sprintf("%x", thumbprint)[:6], nil } -func getResponseObjectAlgFromKID(config *schema.OpenIDConnect, kid, alg string) string { +func getResponseObjectAlgFromKID(config *schema.IdentityProvidersOpenIDConnect, kid, alg string) string { for _, jwk := range config.IssuerPrivateKeys { if kid == jwk.KeyID { return jwk.Algorithm diff --git a/internal/configuration/validator/util_test.go b/internal/configuration/validator/util_test.go index 6a4a8c52c..b1b224b8d 100644 --- a/internal/configuration/validator/util_test.go +++ b/internal/configuration/validator/util_test.go @@ -81,7 +81,7 @@ func TestSchemaJWKGetPropertiesMissingTests(t *testing.T) { } func TestGetResponseObjectAlgFromKID(t *testing.T) { - c := &schema.OpenIDConnect{ + c := &schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {KeyID: "abc", Algorithm: "EX256"}, {KeyID: "123", Algorithm: "EX512"}, diff --git a/internal/configuration/validator/webauthn_test.go b/internal/configuration/validator/webauthn_test.go index ea93f0382..53f8adaa2 100644 --- a/internal/configuration/validator/webauthn_test.go +++ b/internal/configuration/validator/webauthn_test.go @@ -14,7 +14,7 @@ import ( func TestWebAuthnShouldSetDefaultValues(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - WebAuthn: schema.WebAuthnConfiguration{}, + WebAuthn: schema.WebAuthn{}, } ValidateWebAuthn(config, validator) @@ -29,7 +29,7 @@ func TestWebAuthnShouldSetDefaultValues(t *testing.T) { func TestWebAuthnShouldSetDefaultTimeoutWhenNegative(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Timeout: -1, }, } @@ -43,7 +43,7 @@ func TestWebAuthnShouldSetDefaultTimeoutWhenNegative(t *testing.T) { func TestWebAuthnShouldNotSetDefaultValuesWhenConfigured(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ DisplayName: "Test", Timeout: time.Second * 50, ConveyancePreference: protocol.PreferNoAttestation, @@ -81,7 +81,7 @@ func TestWebAuthnShouldNotSetDefaultValuesWhenConfigured(t *testing.T) { func TestWebAuthnShouldRaiseErrorsOnInvalidOptions(t *testing.T) { validator := schema.NewStructValidator() config := &schema.Configuration{ - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ DisplayName: "Test", Timeout: time.Second * 50, ConveyancePreference: "no", diff --git a/internal/handlers/handler_authz_builder.go b/internal/handlers/handler_authz_builder.go index dffa91b34..365966ee9 100644 --- a/internal/handlers/handler_authz_builder.go +++ b/internal/handlers/handler_authz_builder.go @@ -82,7 +82,7 @@ func (b *AuthzBuilder) WithConfig(config *schema.Configuration) *AuthzBuilder { // WithEndpointConfig configures the AuthzBuilder with a *schema.ServerAuthzEndpointConfig. Should be called AFTER // WithConfig or WithAuthzConfig. -func (b *AuthzBuilder) WithEndpointConfig(config schema.ServerAuthzEndpoint) *AuthzBuilder { +func (b *AuthzBuilder) WithEndpointConfig(config schema.ServerEndpointsAuthz) *AuthzBuilder { switch config.Implementation { case AuthzImplForwardAuth.String(): b.WithImplementationForwardAuth() diff --git a/internal/handlers/handler_authz_builder_test.go b/internal/handlers/handler_authz_builder_test.go index dc4bff1fd..e7b145d36 100644 --- a/internal/handlers/handler_authz_builder_test.go +++ b/internal/handlers/handler_authz_builder_test.go @@ -44,33 +44,33 @@ func TestAuthzBuilder_WithConfig(t *testing.T) { func TestAuthzBuilder_WithEndpointConfig(t *testing.T) { builder := NewAuthzBuilder() - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "ExtAuthz", }) assert.Equal(t, AuthzImplExtAuthz, builder.implementation) - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "ForwardAuth", }) assert.Equal(t, AuthzImplForwardAuth, builder.implementation) - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "AuthRequest", }) assert.Equal(t, AuthzImplAuthRequest, builder.implementation) - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "Legacy", }) assert.Equal(t, AuthzImplLegacy, builder.implementation) - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "ExtAuthz", - AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{ + AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{ {Name: "HeaderProxyAuthorization"}, {Name: "CookieSession"}, }, @@ -78,9 +78,9 @@ func TestAuthzBuilder_WithEndpointConfig(t *testing.T) { assert.Len(t, builder.strategies, 2) - builder.WithEndpointConfig(schema.ServerAuthzEndpoint{ + builder.WithEndpointConfig(schema.ServerEndpointsAuthz{ Implementation: "ExtAuthz", - AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{ + AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{ {Name: "HeaderAuthorization"}, {Name: "HeaderProxyAuthorization"}, {Name: "HeaderAuthRequestProxyAuthorization"}, diff --git a/internal/handlers/handler_checks_safe_redirection_test.go b/internal/handlers/handler_checks_safe_redirection_test.go index 27afaacc2..215e40498 100644 --- a/internal/handlers/handler_checks_safe_redirection_test.go +++ b/internal/handlers/handler_checks_safe_redirection_test.go @@ -86,7 +86,8 @@ func TestShouldFailOnInvalidBody(t *testing.T) { }) defer mock.Close() - mock.Ctx.Configuration.Session.Domain = exampleDotCom + + mock.Ctx.Configuration.Session.Domain = exampleDotCom //nolint:staticcheck mock.SetRequestBody(t, "not a valid json") @@ -101,7 +102,8 @@ func TestShouldFailOnInvalidURL(t *testing.T) { AuthenticationLevel: authentication.OneFactor, }) defer mock.Close() - mock.Ctx.Configuration.Session.Domain = exampleDotCom + + mock.Ctx.Configuration.Session.Domain = exampleDotCom //nolint:staticcheck mock.SetRequestBody(t, checkURIWithinDomainRequestBody{ URI: "https//invalid-url", diff --git a/internal/handlers/handler_configuration_test.go b/internal/handlers/handler_configuration_test.go index 29913445c..12dec9465 100644 --- a/internal/handlers/handler_configuration_test.go +++ b/internal/handlers/handler_configuration_test.go @@ -18,9 +18,9 @@ type SecondFactorAvailableMethodsFixture struct { func (s *SecondFactorAvailableMethodsFixture) SetupTest() { s.mock = mocks.NewMockAutheliaCtx(s.T()) s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{}, + Rules: []schema.AccessControlRule{}, }}) } @@ -30,18 +30,18 @@ func (s *SecondFactorAvailableMethodsFixture) TearDownTest() { func (s *SecondFactorAvailableMethodsFixture) TestShouldHaveAllConfiguredMethods() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: false, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: false, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: false, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "two_factor", @@ -60,18 +60,18 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldHaveAllConfiguredMethods func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveTOTPFromAvailableMethodsWhenDisabled() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: false, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: true, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: false, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "two_factor", @@ -90,18 +90,18 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveTOTPFromAvailableM func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveWebAuthnFromAvailableMethodsWhenDisabled() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: false, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: false, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: true, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "two_factor", @@ -120,18 +120,18 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveWebAuthnFromAvaila func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveDuoFromAvailableMethodsWhenNotConfigured() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: true, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: false, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: false, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "two_factor", @@ -150,18 +150,18 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveDuoFromAvailableMe func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveAllMethodsWhenNoTwoFactorACLRulesConfigured() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: false, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: false, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: false, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "one_factor", @@ -180,18 +180,18 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveAllMethodsWhenNoTw func (s *SecondFactorAvailableMethodsFixture) TestShouldRemoveAllMethodsWhenAllDisabledOrNotConfigured() { s.mock.Ctx.Configuration = schema.Configuration{ - DuoAPI: schema.DuoAPIConfiguration{ + DuoAPI: schema.DuoAPI{ Disable: true, }, - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: true, }, - WebAuthn: schema.WebAuthnConfiguration{ + WebAuthn: schema.WebAuthn{ Disable: true, }, - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"example.com"}, Policy: "two_factor", diff --git a/internal/handlers/handler_firstfactor_test.go b/internal/handlers/handler_firstfactor_test.go index 7c59857e7..ff27fa1b4 100644 --- a/internal/handlers/handler_firstfactor_test.go +++ b/internal/handlers/handler_firstfactor_test.go @@ -317,7 +317,7 @@ func (s *FirstFactorRedirectionSuite) SetupTest() { s.mock = mocks.NewMockAutheliaCtx(s.T()) s.mock.Ctx.Configuration.DefaultRedirectionURL = "https://default.local" s.mock.Ctx.Configuration.AccessControl.DefaultPolicy = testBypass - s.mock.Ctx.Configuration.AccessControl.Rules = []schema.ACLRule{ + s.mock.Ctx.Configuration.AccessControl.Rules = []schema.AccessControlRule{ { Domains: []string{"default.local"}, Policy: "one_factor", @@ -404,7 +404,7 @@ func (s *FirstFactorRedirectionSuite) TestShouldRedirectToDefaultURLWhenURLIsUns // the user should receive 200 without redirection URL. func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenNoTargetURLProvidedAndTwoFactorEnabled() { s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "two_factor", }, }) @@ -430,9 +430,9 @@ func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenNoTargetURLProvidedA // the user should receive 200 without redirection URL. func (s *FirstFactorRedirectionSuite) TestShouldReply200WhenUnsafeTargetURLProvidedAndTwoFactorEnabled() { s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(&schema.Configuration{ - AccessControl: schema.AccessControlConfiguration{ + AccessControl: schema.AccessControl{ DefaultPolicy: "one_factor", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"test.example.com"}, Policy: "one_factor", diff --git a/internal/handlers/handler_sign_duo_test.go b/internal/handlers/handler_sign_duo_test.go index d02933177..6602958d5 100644 --- a/internal/handlers/handler_sign_duo_test.go +++ b/internal/handlers/handler_sign_duo_test.go @@ -584,16 +584,12 @@ func (s *SecondFactorDuoPostSuite) TestShouldNotReturnRedirectURL() { func (s *SecondFactorDuoPostSuite) TestShouldRedirectUserToSafeTargetURL() { duoMock := mocks.NewMockAPI(s.mock.Ctrl) - s.mock.Ctx.Configuration.Session.Cookies = []schema.SessionCookieConfiguration{ + s.mock.Ctx.Configuration.Session.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "example.com", - }, + Domain: "example.com", }, { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "mydomain.local", - }, + Domain: "mydomain.local", }, } s.mock.StorageMock.EXPECT(). diff --git a/internal/handlers/handler_sign_totp_test.go b/internal/handlers/handler_sign_totp_test.go index c1c6ea3ab..f062b6c95 100644 --- a/internal/handlers/handler_sign_totp_test.go +++ b/internal/handlers/handler_sign_totp_test.go @@ -144,16 +144,12 @@ func (s *HandlerSignTOTPSuite) TestShouldNotReturnRedirectURL() { func (s *HandlerSignTOTPSuite) TestShouldRedirectUserToSafeTargetURL() { config := model.TOTPConfiguration{ID: 1, Username: "john", Digits: 6, Secret: []byte("secret"), Period: 30, Algorithm: "SHA1"} - s.mock.Ctx.Configuration.Session.Cookies = []schema.SessionCookieConfiguration{ + s.mock.Ctx.Configuration.Session.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "example.com", - }, + Domain: "example.com", }, { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "mydomain.local", - }, + Domain: "mydomain.local", }, } diff --git a/internal/handlers/handler_user_info_test.go b/internal/handlers/handler_user_info_test.go index 8da334dad..6f5760f05 100644 --- a/internal/handlers/handler_user_info_test.go +++ b/internal/handlers/handler_user_info_test.go @@ -206,7 +206,7 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) { HasWebAuthn: false, HasDuo: true, }, - config: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{Disable: true}}, + config: &schema.Configuration{DuoAPI: schema.DuoAPI{Disable: true}}, loadErr: nil, saveErr: nil, }, @@ -225,7 +225,7 @@ func TestUserInfoEndpoint_SetDefaultMethod(t *testing.T) { HasDuo: true, }, config: &schema.Configuration{ - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Disable: true, }, }, diff --git a/internal/logging/logger.go b/internal/logging/logger.go index 34dddea8b..2eb556e58 100644 --- a/internal/logging/logger.go +++ b/internal/logging/logger.go @@ -34,7 +34,7 @@ func LoggerCtxPrintf(level logrus.Level) (logger *CtxPrintfLogger) { } // InitializeLogger configures the default loggers stack levels, formatting, and the output destinations. -func InitializeLogger(config schema.LogConfiguration, log bool) error { +func InitializeLogger(config schema.Log, log bool) error { setLevelStr(config.Level, log) var callerLevels []logrus.Level diff --git a/internal/logging/logger_test.go b/internal/logging/logger_test.go index 0976b494e..65f5054f5 100644 --- a/internal/logging/logger_test.go +++ b/internal/logging/logger_test.go @@ -18,7 +18,7 @@ func TestShouldWriteLogsToFile(t *testing.T) { dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err := InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: false}, false) + err := InitializeLogger(schema.Log{Format: "text", FilePath: path, KeepStdout: false}, false) require.NoError(t, err) Logger().Info("This is a test") @@ -36,7 +36,7 @@ func TestShouldWriteLogsToFileAndStdout(t *testing.T) { dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err := InitializeLogger(schema.LogConfiguration{Format: "text", FilePath: path, KeepStdout: true}, false) + err := InitializeLogger(schema.Log{Format: "text", FilePath: path, KeepStdout: true}, false) require.NoError(t, err) Logger().Info("This is a test") @@ -54,7 +54,7 @@ func TestShouldFormatLogsAsJSON(t *testing.T) { dir := t.TempDir() path := fmt.Sprintf("%s/authelia.log", dir) - err := InitializeLogger(schema.LogConfiguration{Format: "json", FilePath: path, KeepStdout: false}, false) + err := InitializeLogger(schema.Log{Format: "json", FilePath: path, KeepStdout: false}, false) require.NoError(t, err) Logger().Info("This is a test") @@ -69,7 +69,7 @@ func TestShouldFormatLogsAsJSON(t *testing.T) { } func TestShouldRaiseErrorOnInvalidFile(t *testing.T) { - err := InitializeLogger(schema.LogConfiguration{FilePath: "/not/a/valid/path/to.log"}, false) + err := InitializeLogger(schema.Log{FilePath: "/not/a/valid/path/to.log"}, false) switch runtime.GOOS { case "windows": diff --git a/internal/middlewares/password_policy.go b/internal/middlewares/password_policy.go index 7a3aba798..14eb7e0fb 100644 --- a/internal/middlewares/password_policy.go +++ b/internal/middlewares/password_policy.go @@ -14,7 +14,7 @@ type PasswordPolicyProvider interface { } // NewPasswordPolicyProvider returns a new password policy provider. -func NewPasswordPolicyProvider(config schema.PasswordPolicyConfiguration) (provider PasswordPolicyProvider) { +func NewPasswordPolicyProvider(config schema.PasswordPolicy) (provider PasswordPolicyProvider) { if !config.Standard.Enabled && !config.ZXCVBN.Enabled { return &StandardPasswordPolicyProvider{} } diff --git a/internal/middlewares/password_policy_test.go b/internal/middlewares/password_policy_test.go index 0ce9ff899..1d4721a4c 100644 --- a/internal/middlewares/password_policy_test.go +++ b/internal/middlewares/password_policy_test.go @@ -13,47 +13,47 @@ import ( func TestNewPasswordPolicyProvider(t *testing.T) { testCases := []struct { desc string - have schema.PasswordPolicyConfiguration + have schema.PasswordPolicy expected PasswordPolicyProvider }{ { desc: "ShouldReturnUnconfiguredProvider", - have: schema.PasswordPolicyConfiguration{}, + have: schema.PasswordPolicy{}, expected: &StandardPasswordPolicyProvider{}, }, { desc: "ShouldReturnProviderWhenZxcvbn", - have: schema.PasswordPolicyConfiguration{ZXCVBN: schema.PasswordPolicyZXCVBNParams{Enabled: true, MinScore: 10}}, + have: schema.PasswordPolicy{ZXCVBN: schema.PasswordPolicyZXCVBN{Enabled: true, MinScore: 10}}, expected: &ZXCVBNPasswordPolicyProvider{minScore: 10}, }, { desc: "ShouldReturnConfiguredProviderWithMin", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8}}, expected: &StandardPasswordPolicyProvider{min: 8}, }, { desc: "ShouldReturnConfiguredProviderWitHMinMax", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, MaxLength: 100}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, MaxLength: 100}}, expected: &StandardPasswordPolicyProvider{min: 8, max: 100}, }, { desc: "ShouldReturnConfiguredProviderWithMinLowercase", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, RequireLowercase: true}}, expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`)}}, }, { desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercase", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}}, expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`)}}, }, { desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercaseNumber", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireNumber: true}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireNumber: true}}, expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`), *regexp.MustCompile(`[0-9]+`)}}, }, { desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercaseSpecial", - have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireSpecial: true}}, + have: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireSpecial: true}}, expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`), *regexp.MustCompile(`[^a-zA-Z0-9]+`)}}, }, } @@ -69,25 +69,25 @@ func TestNewPasswordPolicyProvider(t *testing.T) { func TestPasswordPolicyProvider_Validate(t *testing.T) { testCases := []struct { desc string - config schema.PasswordPolicyConfiguration + config schema.PasswordPolicy have []string expected []error }{ { desc: "ShouldValidateAllPasswords", - config: schema.PasswordPolicyConfiguration{}, + config: schema.PasswordPolicy{}, have: []string{"a", "1", "a really str0ng pass12nm3kjl12word@@#4"}, expected: []error{nil, nil, nil}, }, { desc: "ShouldValidatePasswordMinLength", - config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8}}, + config: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8}}, have: []string{"a", "b123", "1111111", "aaaaaaaa", "1o23nm1kio2n3k12jn"}, expected: []error{errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, nil, nil}, }, { desc: "ShouldValidatePasswordMaxLength", - config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MaxLength: 30}}, + config: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MaxLength: 30}}, have: []string{ "a1234567894654wkjnkjasnskjandkjansdkjnas", "012345678901234567890123456789a", @@ -99,13 +99,13 @@ func TestPasswordPolicyProvider_Validate(t *testing.T) { }, { desc: "ShouldValidatePasswordAdvancedLowerUpperMin8", - config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}}, + config: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}}, have: []string{"a", "b123", "1111111", "aaaaaaaa", "1o23nm1kio2n3k12jn", "ANJKJQ@#NEK!@#NJK!@#", "qjik2nkjAkjlmn123"}, expected: []error{errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, nil}, }, { desc: "ShouldValidatePasswordAdvancedAllMax100Min8", - config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, MaxLength: 100, RequireLowercase: true, RequireUppercase: true, RequireNumber: true, RequireSpecial: true}}, + config: schema.PasswordPolicy{Standard: schema.PasswordPolicyStandard{Enabled: true, MinLength: 8, MaxLength: 100, RequireLowercase: true, RequireUppercase: true, RequireNumber: true, RequireSpecial: true}}, have: []string{ "a", "b123", diff --git a/internal/mocks/authelia_ctx.go b/internal/mocks/authelia_ctx.go index cd6947673..3de8f2f52 100644 --- a/internal/mocks/authelia_ctx.go +++ b/internal/mocks/authelia_ctx.go @@ -51,28 +51,28 @@ func NewMockAutheliaCtx(t *testing.T) *MockAutheliaCtx { mockAuthelia.Clock.Set(datetime) config := schema.Configuration{} - config.Session.Cookies = []schema.SessionCookieConfiguration{ + config.Session.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "authelia_session", - Domain: "example.com", RememberMe: schema.DefaultSessionConfiguration.RememberMe, Expiration: schema.DefaultSessionConfiguration.Expiration, }, + Domain: "example.com", }, { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: "authelia_session", - Domain: "example2.com", RememberMe: schema.DefaultSessionConfiguration.RememberMe, Expiration: schema.DefaultSessionConfiguration.Expiration, }, + Domain: "example2.com", }, } - config.AccessControl = schema.AccessControlConfiguration{ + config.AccessControl = schema.AccessControl{ DefaultPolicy: "deny", - Rules: []schema.ACLRule{ + Rules: []schema.AccessControlRule{ { Domains: []string{"bypass.example.com"}, Policy: "bypass", diff --git a/internal/notification/file_notifier.go b/internal/notification/file_notifier.go index 9fcb7cdba..3c03700cd 100644 --- a/internal/notification/file_notifier.go +++ b/internal/notification/file_notifier.go @@ -20,7 +20,7 @@ type FileNotifier struct { } // NewFileNotifier create an FileNotifier writing the notification into a file. -func NewFileNotifier(configuration schema.FileSystemNotifierConfiguration) *FileNotifier { +func NewFileNotifier(configuration schema.NotifierFileSystem) *FileNotifier { return &FileNotifier{ path: configuration.Filename, } diff --git a/internal/notification/smtp_auth.go b/internal/notification/smtp_auth.go index 2cf34e4c2..265ad6936 100644 --- a/internal/notification/smtp_auth.go +++ b/internal/notification/smtp_auth.go @@ -12,7 +12,7 @@ import ( ) // NewOpportunisticSMTPAuth is an opportunistic smtp.Auth implementation. -func NewOpportunisticSMTPAuth(config *schema.SMTPNotifierConfiguration) *OpportunisticSMTPAuth { +func NewOpportunisticSMTPAuth(config *schema.NotifierSMTP) *OpportunisticSMTPAuth { if config.Username == "" && config.Password == "" { return nil } diff --git a/internal/notification/smtp_notifier.go b/internal/notification/smtp_notifier.go index 41a873933..bf1c60427 100644 --- a/internal/notification/smtp_notifier.go +++ b/internal/notification/smtp_notifier.go @@ -20,7 +20,7 @@ import ( ) // NewSMTPNotifier creates a SMTPNotifier using the notifier configuration. -func NewSMTPNotifier(config *schema.SMTPNotifierConfiguration, certPool *x509.CertPool) *SMTPNotifier { +func NewSMTPNotifier(config *schema.NotifierSMTP, certPool *x509.CertPool) *SMTPNotifier { var tlsconfig *tls.Config if config.TLS != nil { @@ -74,7 +74,7 @@ func NewSMTPNotifier(config *schema.SMTPNotifierConfiguration, certPool *x509.Ce // SMTPNotifier a notifier to send emails to SMTP servers. type SMTPNotifier struct { - config *schema.SMTPNotifierConfiguration + config *schema.NotifierSMTP domain string random random.Provider tls *tls.Config diff --git a/internal/ntp/ntp.go b/internal/ntp/ntp.go index 2d5d55a01..82bdbb536 100644 --- a/internal/ntp/ntp.go +++ b/internal/ntp/ntp.go @@ -12,7 +12,7 @@ import ( ) // NewProvider instantiate a ntp provider given a configuration. -func NewProvider(config *schema.NTPConfiguration) *Provider { +func NewProvider(config *schema.NTP) *Provider { return &Provider{ config: config, log: logging.Logger(), diff --git a/internal/ntp/ntp_test.go b/internal/ntp/ntp_test.go index 2f3bf92cb..c0e57bb44 100644 --- a/internal/ntp/ntp_test.go +++ b/internal/ntp/ntp_test.go @@ -12,7 +12,7 @@ import ( func TestShouldCheckNTPV4(t *testing.T) { config := &schema.Configuration{ - NTP: schema.NTPConfiguration{ + NTP: schema.NTP{ Address: &schema.AddressUDP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeUDP, "time.cloudflare.com", 123)}, Version: 4, MaximumDesync: time.Second * 3, @@ -29,7 +29,7 @@ func TestShouldCheckNTPV4(t *testing.T) { func TestShouldCheckNTPV3(t *testing.T) { config := &schema.Configuration{ - NTP: schema.NTPConfiguration{ + NTP: schema.NTP{ Address: &schema.AddressUDP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeUDP, "time.cloudflare.com", 123)}, Version: 3, MaximumDesync: time.Second * 3, diff --git a/internal/ntp/types.go b/internal/ntp/types.go index d47e732a6..4e4186e6e 100644 --- a/internal/ntp/types.go +++ b/internal/ntp/types.go @@ -8,7 +8,7 @@ import ( // Provider type is the NTP provider. type Provider struct { - config *schema.NTPConfiguration + config *schema.NTP log *logrus.Logger } diff --git a/internal/oidc/authentication_test.go b/internal/oidc/authentication_test.go index 206a9dffb..3ad361333 100644 --- a/internal/oidc/authentication_test.go +++ b/internal/oidc/authentication_test.go @@ -199,12 +199,12 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { secret := tOpenIDConnectPlainTextClientSecret - s.provider = oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + s.provider = oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ {Key: keyRSA2048, CertificateChain: certRSA2048, Use: oidc.KeyUseSignature, Algorithm: oidc.SigningAlgRSAUsingSHA256}, }, HMACSecret: "abc123", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "hs256", Secret: secret, @@ -335,7 +335,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAUsingSHA256, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: rs256, Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAUsingSHA256, Use: oidc.KeyUseSignature}, }, @@ -350,7 +350,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAUsingSHA384, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "rs384", Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAUsingSHA384, Use: oidc.KeyUseSignature}, }, @@ -365,7 +365,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAUsingSHA512, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "rs512", Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAUsingSHA512, Use: oidc.KeyUseSignature}, }, @@ -380,7 +380,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAPSSUsingSHA256, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "ps256", Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAPSSUsingSHA256, Use: oidc.KeyUseSignature}, }, @@ -395,7 +395,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAPSSUsingSHA384, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "ps384", Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAPSSUsingSHA384, Use: oidc.KeyUseSignature}, }, @@ -410,7 +410,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgRSAPSSUsingSHA512, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "ps512", Key: keyRSA2048.PublicKey, Algorithm: oidc.SigningAlgRSAPSSUsingSHA512, Use: oidc.KeyUseSignature}, }, @@ -425,7 +425,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgECDSAUsingP256AndSHA256, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "es256", Key: keyECDSAP256.PublicKey, Algorithm: oidc.SigningAlgECDSAUsingP256AndSHA256, Use: oidc.KeyUseSignature}, }, @@ -440,7 +440,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgECDSAUsingP384AndSHA384, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "es384", Key: keyECDSAP384.PublicKey, Algorithm: oidc.SigningAlgECDSAUsingP384AndSHA384, Use: oidc.KeyUseSignature}, }, @@ -455,7 +455,7 @@ func (s *ClientAuthenticationStrategySuite) SetupTest() { }, TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretJWT, TokenEndpointAuthSigningAlg: oidc.SigningAlgECDSAUsingP521AndSHA512, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ Values: []schema.JWK{ {KeyID: "es512", Key: keyECDSAP521.PublicKey, Algorithm: oidc.SigningAlgECDSAUsingP521AndSHA512, Use: oidc.KeyUseSignature}, }, diff --git a/internal/oidc/client.go b/internal/oidc/client.go index 71b5ceaa8..d6a8ba529 100644 --- a/internal/oidc/client.go +++ b/internal/oidc/client.go @@ -13,7 +13,7 @@ import ( ) // NewClient creates a new Client. -func NewClient(config schema.OpenIDConnectClient) (client Client) { +func NewClient(config schema.IdentityProvidersOpenIDConnectClient) (client Client) { base := &BaseClient{ ID: config.ID, Description: config.Description, diff --git a/internal/oidc/client_test.go b/internal/oidc/client_test.go index 98d0ee9f8..75ca1740e 100644 --- a/internal/oidc/client_test.go +++ b/internal/oidc/client_test.go @@ -18,7 +18,7 @@ import ( ) func TestNewClient(t *testing.T) { - config := schema.OpenIDConnectClient{} + config := schema.IdentityProvidersOpenIDConnectClient{} client := oidc.NewClient(config) assert.Equal(t, "", client.GetID()) assert.Equal(t, "", client.GetDescription()) @@ -35,7 +35,7 @@ func TestNewClient(t *testing.T) { _, ok = client.(*oidc.FullClient) assert.False(t, ok) - config = schema.OpenIDConnectClient{ + config = schema.IdentityProvidersOpenIDConnectClient{ ID: myclient, Description: myclientdesc, Policy: twofactor, @@ -53,7 +53,7 @@ func TestNewClient(t *testing.T) { assert.Equal(t, fosite.ResponseModeFormPost, client.GetResponseModes()[0]) assert.Equal(t, authorization.TwoFactor, client.GetAuthorizationPolicy()) - config = schema.OpenIDConnectClient{ + config = schema.IdentityProvidersOpenIDConnectClient{ TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretPost, } @@ -377,7 +377,7 @@ func TestClient_GetResponseTypes(t *testing.T) { func TestNewClientPKCE(t *testing.T) { testCases := []struct { name string - have schema.OpenIDConnectClient + have schema.IdentityProvidersOpenIDConnectClient expectedEnforcePKCE bool expectedEnforcePKCEChallengeMethod bool expected string @@ -387,7 +387,7 @@ func TestNewClientPKCE(t *testing.T) { }{ { "ShouldNotEnforcePKCEAndNotErrorOnNonPKCERequest", - schema.OpenIDConnectClient{}, + schema.IdentityProvidersOpenIDConnectClient{}, false, false, "", @@ -397,7 +397,7 @@ func TestNewClientPKCE(t *testing.T) { }, { "ShouldEnforcePKCEAndErrorOnNonPKCERequest", - schema.OpenIDConnectClient{EnforcePKCE: true}, + schema.IdentityProvidersOpenIDConnectClient{EnforcePKCE: true}, true, false, "", @@ -407,7 +407,7 @@ func TestNewClientPKCE(t *testing.T) { }, { "ShouldEnforcePKCEAndNotErrorOnPKCERequest", - schema.OpenIDConnectClient{EnforcePKCE: true}, + schema.IdentityProvidersOpenIDConnectClient{EnforcePKCE: true}, true, false, "", @@ -416,7 +416,7 @@ func TestNewClientPKCE(t *testing.T) { "", }, {"ShouldEnforcePKCEFromChallengeMethodAndErrorOnNonPKCERequest", - schema.OpenIDConnectClient{PKCEChallengeMethod: "S256"}, + schema.IdentityProvidersOpenIDConnectClient{PKCEChallengeMethod: "S256"}, true, true, "S256", @@ -425,7 +425,7 @@ func TestNewClientPKCE(t *testing.T) { "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Clients must include a code_challenge when performing the authorize code flow, but it is missing. The server is configured in a way that enforces PKCE for this client.", }, {"ShouldEnforcePKCEFromChallengeMethodAndErrorOnInvalidChallengeMethod", - schema.OpenIDConnectClient{PKCEChallengeMethod: "S256"}, + schema.IdentityProvidersOpenIDConnectClient{PKCEChallengeMethod: "S256"}, true, true, "S256", @@ -434,7 +434,7 @@ func TestNewClientPKCE(t *testing.T) { "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Client must use code_challenge_method=S256, is not allowed. The server is configured in a way that enforces PKCE S256 as challenge method for this client.", }, {"ShouldEnforcePKCEFromChallengeMethodAndNotErrorOnValidRequest", - schema.OpenIDConnectClient{PKCEChallengeMethod: "S256"}, + schema.IdentityProvidersOpenIDConnectClient{PKCEChallengeMethod: "S256"}, true, true, "S256", @@ -470,7 +470,7 @@ func TestNewClientPKCE(t *testing.T) { func TestNewClientPAR(t *testing.T) { testCases := []struct { name string - have schema.OpenIDConnectClient + have schema.IdentityProvidersOpenIDConnectClient expected bool r *fosite.Request err string @@ -478,7 +478,7 @@ func TestNewClientPAR(t *testing.T) { }{ { "ShouldNotEnforcEPARAndNotErrorOnNonPARRequest", - schema.OpenIDConnectClient{}, + schema.IdentityProvidersOpenIDConnectClient{}, false, &fosite.Request{}, "", @@ -486,7 +486,7 @@ func TestNewClientPAR(t *testing.T) { }, { "ShouldEnforcePARAndErrorOnNonPARRequest", - schema.OpenIDConnectClient{EnforcePAR: true}, + schema.IdentityProvidersOpenIDConnectClient{EnforcePAR: true}, true, &fosite.Request{}, "invalid_request", @@ -494,14 +494,14 @@ func TestNewClientPAR(t *testing.T) { }, { "ShouldEnforcePARAndErrorOnNonPARRequest", - schema.OpenIDConnectClient{EnforcePAR: true}, + schema.IdentityProvidersOpenIDConnectClient{EnforcePAR: true}, true, &fosite.Request{Form: map[string][]string{oidc.FormParameterRequestURI: {"https://example.com"}}}, "invalid_request", "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Pushed Authorization Requests are enforced for this client but no such request was sent. The request_uri parameter 'https://example.com' is malformed."}, { "ShouldEnforcePARAndNotErrorOnPARRequest", - schema.OpenIDConnectClient{EnforcePAR: true}, + schema.IdentityProvidersOpenIDConnectClient{EnforcePAR: true}, true, &fosite.Request{Form: map[string][]string{oidc.FormParameterRequestURI: {fmt.Sprintf("%sabc", oidc.RedirectURIPrefixPushedAuthorizationRequestURN)}}}, "", @@ -533,7 +533,7 @@ func TestNewClientPAR(t *testing.T) { func TestNewClientResponseModes(t *testing.T) { testCases := []struct { name string - have schema.OpenIDConnectClient + have schema.IdentityProvidersOpenIDConnectClient expected []fosite.ResponseModeType r *fosite.AuthorizeRequest err string @@ -541,7 +541,7 @@ func TestNewClientResponseModes(t *testing.T) { }{ { "ShouldEnforceResponseModePolicyAndAllowDefaultModeQuery", - schema.OpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeQuery}}, + schema.IdentityProvidersOpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeQuery}}, []fosite.ResponseModeType{fosite.ResponseModeQuery}, &fosite.AuthorizeRequest{DefaultResponseMode: fosite.ResponseModeQuery, ResponseMode: fosite.ResponseModeDefault, Request: fosite.Request{Form: map[string][]string{oidc.FormParameterResponseMode: nil}}}, "", @@ -549,7 +549,7 @@ func TestNewClientResponseModes(t *testing.T) { }, { "ShouldEnforceResponseModePolicyAndFailOnDefaultMode", - schema.OpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeFormPost}}, + schema.IdentityProvidersOpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeFormPost}}, []fosite.ResponseModeType{fosite.ResponseModeFormPost}, &fosite.AuthorizeRequest{DefaultResponseMode: fosite.ResponseModeQuery, ResponseMode: fosite.ResponseModeDefault, Request: fosite.Request{Form: map[string][]string{oidc.FormParameterResponseMode: nil}}}, "unsupported_response_mode", @@ -557,7 +557,7 @@ func TestNewClientResponseModes(t *testing.T) { }, { "ShouldNotEnforceConfiguredResponseMode", - schema.OpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeFormPost}}, + schema.IdentityProvidersOpenIDConnectClient{ResponseModes: []string{oidc.ResponseModeFormPost}}, []fosite.ResponseModeType{fosite.ResponseModeFormPost}, &fosite.AuthorizeRequest{DefaultResponseMode: fosite.ResponseModeQuery, ResponseMode: fosite.ResponseModeQuery, Request: fosite.Request{Form: map[string][]string{oidc.FormParameterResponseMode: {oidc.ResponseModeQuery}}}}, "", @@ -565,7 +565,7 @@ func TestNewClientResponseModes(t *testing.T) { }, { "ShouldNotEnforceUnconfiguredResponseMode", - schema.OpenIDConnectClient{ResponseModes: []string{}}, + schema.IdentityProvidersOpenIDConnectClient{ResponseModes: []string{}}, []fosite.ResponseModeType{}, &fosite.AuthorizeRequest{DefaultResponseMode: fosite.ResponseModeQuery, ResponseMode: fosite.ResponseModeDefault, Request: fosite.Request{Form: map[string][]string{oidc.FormParameterResponseMode: {oidc.ResponseModeQuery}}}}, "", @@ -610,9 +610,9 @@ func TestNewClient_JSONWebKeySetURI(t *testing.T) { ok bool ) - client = oidc.NewClient(schema.OpenIDConnectClient{ + client = oidc.NewClient(schema.IdentityProvidersOpenIDConnectClient{ TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretPost, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ URI: MustParseRequestURI("https://google.com"), }, }) @@ -625,9 +625,9 @@ func TestNewClient_JSONWebKeySetURI(t *testing.T) { assert.Equal(t, "https://google.com", clientf.GetJSONWebKeysURI()) - client = oidc.NewClient(schema.OpenIDConnectClient{ + client = oidc.NewClient(schema.IdentityProvidersOpenIDConnectClient{ TokenEndpointAuthMethod: oidc.ClientAuthMethodClientSecretPost, - PublicKeys: schema.OpenIDConnectClientPublicKeys{ + PublicKeys: schema.IdentityProvidersOpenIDConnectClientPublicKeys{ URI: nil, }, }) diff --git a/internal/oidc/config.go b/internal/oidc/config.go index 44fe989c0..de189da7a 100644 --- a/internal/oidc/config.go +++ b/internal/oidc/config.go @@ -23,7 +23,7 @@ import ( "github.com/authelia/authelia/v4/internal/utils" ) -func NewConfig(config *schema.OpenIDConnect, templates *templates.Provider) (c *Config) { +func NewConfig(config *schema.IdentityProvidersOpenIDConnect, templates *templates.Provider) (c *Config) { c = &Config{ GlobalSecret: []byte(utils.HashSHA256FromString(config.HMACSecret)), SendDebugMessagesToClients: config.EnableClientDebugMessages, diff --git a/internal/oidc/discovery.go b/internal/oidc/discovery.go index b3c147f89..435f2db1b 100644 --- a/internal/oidc/discovery.go +++ b/internal/oidc/discovery.go @@ -8,7 +8,7 @@ import ( ) // NewOpenIDConnectWellKnownConfiguration generates a new OpenIDConnectWellKnownConfiguration. -func NewOpenIDConnectWellKnownConfiguration(c *schema.OpenIDConnect) (config OpenIDConnectWellKnownConfiguration) { +func NewOpenIDConnectWellKnownConfiguration(c *schema.IdentityProvidersOpenIDConnect) (config OpenIDConnectWellKnownConfiguration) { config = OpenIDConnectWellKnownConfiguration{ OAuth2WellKnownConfiguration: OAuth2WellKnownConfiguration{ CommonDiscoveryOptions: CommonDiscoveryOptions{ diff --git a/internal/oidc/discovery_test.go b/internal/oidc/discovery_test.go index 24e033f02..6d1722611 100644 --- a/internal/oidc/discovery_test.go +++ b/internal/oidc/discovery_test.go @@ -67,9 +67,9 @@ func TestNewOpenIDConnectWellKnownConfiguration(t *testing.T) { for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - c := schema.OpenIDConnect{ + c := schema.IdentityProvidersOpenIDConnect{ EnablePKCEPlainChallenge: tc.pkcePlainChallenge, - PAR: schema.OpenIDConnectPAR{ + PAR: schema.IdentityProvidersOpenIDConnectPAR{ Enforce: tc.enforcePAR, }, Discovery: tc.discovery, @@ -102,12 +102,12 @@ func TestNewOpenIDConnectWellKnownConfiguration(t *testing.T) { } func TestNewOpenIDConnectProviderDiscovery(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, HMACSecret: "asbdhaaskmdlkamdklasmdlkams", EnablePKCEPlainChallenge: true, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "a-client", Secret: tOpenIDConnectPlainTextClientSecret, @@ -143,11 +143,11 @@ func TestNewOpenIDConnectProviderDiscovery(t *testing.T) { } func TestNewOpenIDConnectProvider_GetOpenIDConnectWellKnownConfiguration(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, HMACSecret: "asbdhaaskmdlkamdklasmdlkams", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "a-client", Secret: tOpenIDConnectPlainTextClientSecret, @@ -248,11 +248,11 @@ func TestNewOpenIDConnectProvider_GetOpenIDConnectWellKnownConfiguration(t *test } func TestNewOpenIDConnectProvider_GetOAuth2WellKnownConfiguration(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, HMACSecret: "asbdhaaskmdlkamdklasmdlkams", - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "a-client", Secret: tOpenIDConnectPlainTextClientSecret, @@ -338,12 +338,12 @@ func TestNewOpenIDConnectProvider_GetOAuth2WellKnownConfiguration(t *testing.T) } func TestNewOpenIDConnectProvider_GetOpenIDConnectWellKnownConfigurationWithPlainPKCE(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, HMACSecret: "asbdhaaskmdlkamdklasmdlkams", EnablePKCEPlainChallenge: true, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "a-client", Secret: tOpenIDConnectPlainTextClientSecret, diff --git a/internal/oidc/keys.go b/internal/oidc/keys.go index 3503a555f..e8fc86bb2 100644 --- a/internal/oidc/keys.go +++ b/internal/oidc/keys.go @@ -19,7 +19,7 @@ import ( ) // NewKeyManager news up a KeyManager. -func NewKeyManager(config *schema.OpenIDConnect) (manager *KeyManager) { +func NewKeyManager(config *schema.IdentityProvidersOpenIDConnect) (manager *KeyManager) { manager = &KeyManager{ alg2kid: config.Discovery.DefaultKeyIDs, kids: map[string]*JWK{}, diff --git a/internal/oidc/keys_blackbox_test.go b/internal/oidc/keys_blackbox_test.go index 8b25729b0..d34057534 100644 --- a/internal/oidc/keys_blackbox_test.go +++ b/internal/oidc/keys_blackbox_test.go @@ -17,7 +17,7 @@ import ( ) func TestKeyManager(t *testing.T) { - config := &schema.OpenIDConnect{ + config := &schema.IdentityProvidersOpenIDConnect{ IssuerPrivateKeys: []schema.JWK{ { Use: oidc.KeyUseSignature, diff --git a/internal/oidc/provider.go b/internal/oidc/provider.go index 915951920..2064e970a 100644 --- a/internal/oidc/provider.go +++ b/internal/oidc/provider.go @@ -13,7 +13,7 @@ import ( ) // NewOpenIDConnectProvider new-ups a OpenIDConnectProvider. -func NewOpenIDConnectProvider(config *schema.OpenIDConnect, store storage.Provider, templates *templates.Provider) (provider *OpenIDConnectProvider) { +func NewOpenIDConnectProvider(config *schema.IdentityProvidersOpenIDConnect, store storage.Provider, templates *templates.Provider) (provider *OpenIDConnectProvider) { if config == nil { return nil } diff --git a/internal/oidc/provider_test.go b/internal/oidc/provider_test.go index 5d5fc33f9..07ed47a36 100644 --- a/internal/oidc/provider_test.go +++ b/internal/oidc/provider_test.go @@ -18,12 +18,12 @@ func TestOpenIDConnectProvider_NewOpenIDConnectProvider_NotConfigured(t *testing } func TestNewOpenIDConnectProvider_ShouldEnableOptionalDiscoveryValues(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, EnablePKCEPlainChallenge: true, HMACSecret: badhmac, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: myclient, Secret: tOpenIDConnectPlainTextClientSecret, @@ -50,11 +50,11 @@ func TestNewOpenIDConnectProvider_ShouldEnableOptionalDiscoveryValues(t *testing } func TestOpenIDConnectProvider_NewOpenIDConnectProvider_GoodConfiguration(t *testing.T) { - provider := oidc.NewOpenIDConnectProvider(&schema.OpenIDConnect{ + provider := oidc.NewOpenIDConnectProvider(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, HMACSecret: badhmac, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "a-client", Secret: tOpenIDConnectPlainTextClientSecret, diff --git a/internal/oidc/store.go b/internal/oidc/store.go index c39b52530..628f2c6ad 100644 --- a/internal/oidc/store.go +++ b/internal/oidc/store.go @@ -19,7 +19,7 @@ import ( ) // NewStore returns a Store when provided with a schema.OpenIDConnect and storage.Provider. -func NewStore(config *schema.OpenIDConnect, provider storage.Provider) (store *Store) { +func NewStore(config *schema.IdentityProvidersOpenIDConnect, provider storage.Provider) (store *Store) { logger := logging.Logger() store = &Store{ diff --git a/internal/oidc/store_test.go b/internal/oidc/store_test.go index 2cf670e9c..9f1c32fed 100644 --- a/internal/oidc/store_test.go +++ b/internal/oidc/store_test.go @@ -24,10 +24,10 @@ import ( ) func TestOpenIDConnectStore_GetClientPolicy(t *testing.T) { - s := oidc.NewStore(&schema.OpenIDConnect{ + s := oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: myclient, Description: myclientdesc, @@ -56,10 +56,10 @@ func TestOpenIDConnectStore_GetClientPolicy(t *testing.T) { } func TestOpenIDConnectStore_GetInternalClient(t *testing.T) { - s := oidc.NewStore(&schema.OpenIDConnect{ + s := oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: myclient, Description: myclientdesc, @@ -83,7 +83,7 @@ func TestOpenIDConnectStore_GetInternalClient(t *testing.T) { func TestOpenIDConnectStore_GetInternalClient_ValidClient(t *testing.T) { id := myclient - c1 := schema.OpenIDConnectClient{ + c1 := schema.IdentityProvidersOpenIDConnectClient{ ID: id, Description: myclientdesc, Policy: onefactor, @@ -91,10 +91,10 @@ func TestOpenIDConnectStore_GetInternalClient_ValidClient(t *testing.T) { Secret: tOpenIDConnectPlainTextClientSecret, } - s := oidc.NewStore(&schema.OpenIDConnect{ + s := oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{c1}, + Clients: []schema.IdentityProvidersOpenIDConnectClient{c1}, }, nil) client, err := s.GetFullClient(id) @@ -111,7 +111,7 @@ func TestOpenIDConnectStore_GetInternalClient_ValidClient(t *testing.T) { } func TestOpenIDConnectStore_GetInternalClient_InvalidClient(t *testing.T) { - c1 := schema.OpenIDConnectClient{ + c1 := schema.IdentityProvidersOpenIDConnectClient{ ID: myclient, Description: myclientdesc, Policy: onefactor, @@ -119,10 +119,10 @@ func TestOpenIDConnectStore_GetInternalClient_InvalidClient(t *testing.T) { Secret: tOpenIDConnectPlainTextClientSecret, } - s := oidc.NewStore(&schema.OpenIDConnect{ + s := oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{c1}, + Clients: []schema.IdentityProvidersOpenIDConnectClient{c1}, }, nil) client, err := s.GetFullClient("another-client") @@ -131,10 +131,10 @@ func TestOpenIDConnectStore_GetInternalClient_InvalidClient(t *testing.T) { } func TestOpenIDConnectStore_IsValidClientID(t *testing.T) { - s := oidc.NewStore(&schema.OpenIDConnect{ + s := oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ IssuerCertificateChain: schema.X509CertificateChain{}, IssuerPrivateKey: keyRSA2048, - Clients: []schema.OpenIDConnectClient{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: myclient, Description: myclientdesc, @@ -169,8 +169,8 @@ func (s *StoreSuite) SetupTest() { s.ctx = context.Background() s.ctrl = gomock.NewController(s.T()) s.mock = mocks.NewMockStorage(s.ctrl) - s.store = oidc.NewStore(&schema.OpenIDConnect{ - Clients: []schema.OpenIDConnectClient{ + s.store = oidc.NewStore(&schema.IdentityProvidersOpenIDConnect{ + Clients: []schema.IdentityProvidersOpenIDConnectClient{ { ID: "hs256", Secret: tOpenIDConnectPBKDF2ClientSecret, diff --git a/internal/regulation/regulator.go b/internal/regulation/regulator.go index ab1995483..9fe79d039 100644 --- a/internal/regulation/regulator.go +++ b/internal/regulation/regulator.go @@ -12,7 +12,7 @@ import ( ) // NewRegulator create a regulator instance. -func NewRegulator(config schema.RegulationConfiguration, store storage.RegulatorProvider, clock utils.Clock) *Regulator { +func NewRegulator(config schema.Regulation, store storage.RegulatorProvider, clock utils.Clock) *Regulator { return &Regulator{ enabled: config.MaxRetries > 0, store: store, diff --git a/internal/regulation/regulator_test.go b/internal/regulation/regulator_test.go index a7156dbd0..536d674ae 100644 --- a/internal/regulation/regulator_test.go +++ b/internal/regulation/regulator_test.go @@ -25,7 +25,7 @@ type RegulatorSuite struct { func (s *RegulatorSuite) SetupTest() { s.mock = mocks.NewMockAutheliaCtx(s.T()) - s.mock.Ctx.Configuration.Regulation = schema.RegulationConfiguration{ + s.mock.Ctx.Configuration.Regulation = schema.Regulation{ MaxRetries: 3, BanTime: time.Second * 180, FindTime: time.Second * 30, @@ -307,7 +307,7 @@ func (s *RegulatorSuite) TestShouldHaveRegulatorDisabled() { Return(attemptsInDB, nil) // Check Disabled Functionality. - config := schema.RegulationConfiguration{ + config := schema.Regulation{ MaxRetries: 0, FindTime: time.Second * 180, BanTime: time.Second * 180, @@ -318,7 +318,7 @@ func (s *RegulatorSuite) TestShouldHaveRegulatorDisabled() { assert.NoError(s.T(), err) // Check Enabled Functionality. - config = schema.RegulationConfiguration{ + config = schema.Regulation{ MaxRetries: 1, FindTime: time.Second * 180, BanTime: time.Second * 180, diff --git a/internal/regulation/types.go b/internal/regulation/types.go index 11c56fec0..5c0f5edea 100644 --- a/internal/regulation/types.go +++ b/internal/regulation/types.go @@ -14,7 +14,7 @@ type Regulator struct { // Is the regulation enabled. enabled bool - config schema.RegulationConfiguration + config schema.Regulation store storage.RegulatorProvider diff --git a/internal/server/server_test.go b/internal/server/server_test.go index dd5429939..d0974a027 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -189,7 +189,7 @@ func TestShouldRaiseErrorWhenClientDoesNotSkipVerify(t *testing.T) { defer certificateContext.Close() tlsServerContext, err := NewTLSServerContext(schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: &schema.AddressTCP{Address: schema.NewAddressFromNetworkValues("tcp", "0.0.0.0", 9091)}, TLS: schema.ServerTLS{ Certificate: certificateContext.Certificates[0].CertFile.Name(), @@ -218,7 +218,7 @@ func TestShouldServeOverTLSWhenClientDoesSkipVerify(t *testing.T) { defer certificateContext.Close() tlsServerContext, err := NewTLSServerContext(schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: schema.DefaultServerConfiguration.Address, TLS: schema.ServerTLS{ Certificate: certificateContext.Certificates[0].CertFile.Name(), @@ -256,7 +256,7 @@ func TestShouldServeOverTLSWhenClientHasProperRootCA(t *testing.T) { defer certificateContext.Close() tlsServerContext, err := NewTLSServerContext(schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: schema.DefaultServerConfiguration.Address, TLS: schema.ServerTLS{ Certificate: certificateContext.Certificates[0].CertFile.Name(), @@ -308,7 +308,7 @@ func TestShouldRaiseWhenMutualTLSIsConfiguredAndClientIsNotAuthenticated(t *test require.NoError(t, err) tlsServerContext, err := NewTLSServerContext(schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: schema.DefaultServerConfiguration.Address, TLS: schema.ServerTLS{ Certificate: certificateContext.Certificates[0].CertFile.Name(), @@ -352,7 +352,7 @@ func TestShouldServeProperlyWhenMutualTLSIsConfiguredAndClientIsAuthenticated(t require.NoError(t, err) tlsServerContext, err := NewTLSServerContext(schema.Configuration{ - Server: schema.ServerConfiguration{ + Server: schema.Server{ Address: schema.DefaultServerConfiguration.Address, TLS: schema.ServerTLS{ Certificate: certificateContext.Certificates[0].CertFile.Name(), diff --git a/internal/server/template.go b/internal/server/template.go index 869e8e7a7..45fe83ba1 100644 --- a/internal/server/template.go +++ b/internal/server/template.go @@ -52,7 +52,7 @@ func ServeTemplatedFile(t templates.Template, opts *TemplatedFileOptions) middle switch { case ctx.Configuration.Server.Headers.CSPTemplate != "": - ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, strings.ReplaceAll(ctx.Configuration.Server.Headers.CSPTemplate, placeholderCSPNonce, nonce)) + ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, strings.ReplaceAll(string(ctx.Configuration.Server.Headers.CSPTemplate), placeholderCSPNonce, nonce)) case isDevEnvironment: ctx.Response.Header.Add(fasthttp.HeaderContentSecurityPolicy, fmt.Sprintf(tmplCSPDevelopment, nonce)) default: @@ -313,7 +313,7 @@ type TemplatedFileOptions struct { EndpointsDuo bool EndpointsOpenIDConnect bool - EndpointsAuthz map[string]schema.ServerAuthzEndpoint + EndpointsAuthz map[string]schema.ServerEndpointsAuthz } // CommonData returns a TemplatedFileCommonData with the dynamic options. @@ -404,5 +404,5 @@ type TemplatedFileOpenAPIData struct { Duo bool OpenIDConnect bool - EndpointsAuthz map[string]schema.ServerAuthzEndpoint + EndpointsAuthz map[string]schema.ServerEndpointsAuthz } diff --git a/internal/server/template_test.go b/internal/server/template_test.go index 8a422f1b6..1f4f31cef 100644 --- a/internal/server/template_test.go +++ b/internal/server/template_test.go @@ -52,12 +52,11 @@ func TestShouldTemplateOpenAPI(t *testing.T) { mock := mocks.NewMockAutheliaCtx(t) mock.Ctx.Configuration.Server = schema.DefaultServerConfiguration - mock.Ctx.Configuration.Session = schema.SessionConfiguration{ - Cookies: []schema.SessionCookieConfiguration{ + mock.Ctx.Configuration.Session = schema.Session{ + Cookies: []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ - Domain: "example.com", - }, + Domain: "example.com", + AutheliaURL: &url.URL{Scheme: "https", Host: "auth.example.com", Path: "/"}, }, }, diff --git a/internal/session/provider.go b/internal/session/provider.go index 4d6e5091d..2cf227a02 100644 --- a/internal/session/provider.go +++ b/internal/session/provider.go @@ -16,7 +16,7 @@ type Provider struct { } // NewProvider instantiate a session provider given a configuration. -func NewProvider(config schema.SessionConfiguration, certPool *x509.CertPool) *Provider { +func NewProvider(config schema.Session, certPool *x509.CertPool) *Provider { log := logging.Logger() name, p, s, err := NewSessionProvider(config, certPool) diff --git a/internal/session/provider_config.go b/internal/session/provider_config.go index f61842d7a..7f611b773 100644 --- a/internal/session/provider_config.go +++ b/internal/session/provider_config.go @@ -19,7 +19,7 @@ import ( ) // NewProviderConfig creates a configuration for creating the session provider. -func NewProviderConfig(config schema.SessionCookieConfiguration, providerName string, serializer Serializer) ProviderConfig { +func NewProviderConfig(config schema.SessionCookie, providerName string, serializer Serializer) ProviderConfig { c := session.NewDefaultConfig() c.SessionIDGeneratorFunc = func() []byte { @@ -83,7 +83,7 @@ func NewProviderSession(pconfig ProviderConfig, provider session.Provider) (p *s return p, nil } -func NewProviderConfigAndSession(config schema.SessionCookieConfiguration, providerName string, serializer Serializer, provider session.Provider) (c ProviderConfig, p *session.Session, err error) { +func NewProviderConfigAndSession(config schema.SessionCookie, providerName string, serializer Serializer, provider session.Provider) (c ProviderConfig, p *session.Session, err error) { c = NewProviderConfig(config, providerName, serializer) if p, err = NewProviderSession(c, provider); err != nil { @@ -93,7 +93,7 @@ func NewProviderConfigAndSession(config schema.SessionCookieConfiguration, provi return c, p, nil } -func NewSessionProvider(config schema.SessionConfiguration, certPool *x509.CertPool) (name string, provider session.Provider, serializer Serializer, err error) { +func NewSessionProvider(config schema.Session, certPool *x509.CertPool) (name string, provider session.Provider, serializer Serializer, err error) { // If redis configuration is provided, then use the redis provider. switch { case config.Redis != nil: diff --git a/internal/session/provider_test.go b/internal/session/provider_test.go index c6c09cf7d..f5c4533c9 100644 --- a/internal/session/provider_test.go +++ b/internal/session/provider_test.go @@ -14,14 +14,14 @@ import ( ) func newTestSession() (*Session, error) { - config := schema.SessionConfiguration{} - config.Cookies = []schema.SessionCookieConfiguration{ + config := schema.Session{} + config.Cookies = []schema.SessionCookie{ { - SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ + SessionCookieCommon: schema.SessionCookieCommon{ Name: testName, - Domain: testDomain, Expiration: testExpiration, }, + Domain: testDomain, }, } diff --git a/internal/session/session.go b/internal/session/session.go index 5d4e9577e..7306b579d 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -12,7 +12,7 @@ import ( // Session a session provider. type Session struct { - Config schema.SessionCookieConfiguration + Config schema.SessionCookie sessionHolder *session.Session } diff --git a/internal/storage/sql_provider_backend_mysql.go b/internal/storage/sql_provider_backend_mysql.go index 5ff2e531a..6ed4ad640 100644 --- a/internal/storage/sql_provider_backend_mysql.go +++ b/internal/storage/sql_provider_backend_mysql.go @@ -30,7 +30,7 @@ func NewMySQLProvider(config *schema.Configuration, caCertPool *x509.CertPool) ( return provider } -func dsnMySQL(config *schema.MySQLStorageConfiguration, caCertPool *x509.CertPool) (dataSourceName string) { +func dsnMySQL(config *schema.StorageMySQL, caCertPool *x509.CertPool) (dataSourceName string) { dsnConfig := mysql.NewConfig() dsnConfig.Net = config.Address.Network() diff --git a/internal/storage/sql_provider_backend_postgres.go b/internal/storage/sql_provider_backend_postgres.go index ef7054951..38fb151e5 100644 --- a/internal/storage/sql_provider_backend_postgres.go +++ b/internal/storage/sql_provider_backend_postgres.go @@ -132,7 +132,7 @@ func NewPostgreSQLProvider(config *schema.Configuration, caCertPool *x509.CertPo return provider } -func dsnPostgreSQL(config *schema.PostgreSQLStorageConfiguration, globalCACertPool *x509.CertPool) (dsn string) { +func dsnPostgreSQL(config *schema.StoragePostgreSQL, globalCACertPool *x509.CertPool) (dsn string) { dsnConfig, _ := pgx.ParseConfig("") dsnConfig.Host = config.Address.SocketHostname() @@ -153,16 +153,26 @@ func dsnPostgreSQL(config *schema.PostgreSQLStorageConfiguration, globalCACertPo return stdlib.RegisterConnConfig(dsnConfig) } -func loadPostgreSQLTLSConfig(config *schema.PostgreSQLStorageConfiguration, globalCACertPool *x509.CertPool) (tlsConfig *tls.Config) { - if config.TLS == nil && config.SSL == nil { - return nil - } - +func loadPostgreSQLTLSConfig(config *schema.StoragePostgreSQL, globalCACertPool *x509.CertPool) (tlsConfig *tls.Config) { if config.TLS != nil { return utils.NewTLSConfig(config.TLS, globalCACertPool) } - ca, certs := loadPostgreSQLLegacyTLSConfig(config) + return loadPostgreSQLLegacyTLSConfig(config, globalCACertPool) +} + +//nolint:staticcheck // Used for legacy purposes. +func loadPostgreSQLLegacyTLSConfig(config *schema.StoragePostgreSQL, globalCACertPool *x509.CertPool) (tlsConfig *tls.Config) { + if config.SSL == nil { + return nil + } + + var ( + ca *x509.Certificate + certs []tls.Certificate + ) + + ca, certs = loadPostgreSQLLegacyTLSConfigFiles(config) switch config.SSL.Mode { case "disable": @@ -196,7 +206,8 @@ func loadPostgreSQLTLSConfig(config *schema.PostgreSQLStorageConfiguration, glob return tlsConfig } -func loadPostgreSQLLegacyTLSConfig(config *schema.PostgreSQLStorageConfiguration) (ca *x509.Certificate, certs []tls.Certificate) { +//nolint:staticcheck // Used for legacy purposes. +func loadPostgreSQLLegacyTLSConfigFiles(config *schema.StoragePostgreSQL) (ca *x509.Certificate, certs []tls.Certificate) { var ( err error ) diff --git a/internal/suites/const.go b/internal/suites/const.go index 3deddf064..18e8ddb4a 100644 --- a/internal/suites/const.go +++ b/internal/suites/const.go @@ -92,13 +92,13 @@ const ( var ( storageLocalTmpConfig = schema.Configuration{ - TOTP: schema.TOTPConfiguration{ + TOTP: schema.TOTP{ Issuer: "Authelia", Period: 6, }, - Storage: schema.StorageConfiguration{ + Storage: schema.Storage{ EncryptionKey: "a_not_so_secure_encryption_key", - Local: &schema.LocalStorageConfiguration{ + Local: &schema.StorageLocal{ Path: "/tmp/db.sqlite3", }, }, diff --git a/internal/totp/totp.go b/internal/totp/totp.go index 30cfcecc0..093115b05 100644 --- a/internal/totp/totp.go +++ b/internal/totp/totp.go @@ -13,7 +13,7 @@ import ( ) // NewTimeBasedProvider creates a new totp.TimeBased which implements the totp.Provider. -func NewTimeBasedProvider(config schema.TOTPConfiguration) (provider *TimeBased) { +func NewTimeBasedProvider(config schema.TOTP) (provider *TimeBased) { provider = &TimeBased{ config: &config, } @@ -29,7 +29,7 @@ func NewTimeBasedProvider(config schema.TOTPConfiguration) (provider *TimeBased) // TimeBased totp.Provider for production use. type TimeBased struct { - config *schema.TOTPConfiguration + config *schema.TOTP skew uint } diff --git a/internal/totp/totp_test.go b/internal/totp/totp_test.go index 34b421eed..f685f1293 100644 --- a/internal/totp/totp_test.go +++ b/internal/totp/totp_test.go @@ -80,7 +80,7 @@ func TestTOTPGenerateCustom(t *testing.T) { }, } - totp := NewTimeBasedProvider(schema.TOTPConfiguration{ + totp := NewTimeBasedProvider(schema.TOTP{ Issuer: "Authelia", Algorithm: "SHA1", Digits: 6, @@ -120,7 +120,7 @@ func TestTOTPGenerateCustom(t *testing.T) { func TestTOTPGenerate(t *testing.T) { skew := uint(2) - totp := NewTimeBasedProvider(schema.TOTPConfiguration{ + totp := NewTimeBasedProvider(schema.TOTP{ Issuer: "Authelia", Algorithm: "SHA256", Digits: 8, diff --git a/internal/utils/crypto.go b/internal/utils/crypto.go index d8afd2d4c..95a61176d 100644 --- a/internal/utils/crypto.go +++ b/internal/utils/crypto.go @@ -302,8 +302,8 @@ func IsX509PrivateKey(i any) bool { } } -// NewTLSConfig generates a tls.Config from a schema.TLSConfig and a x509.CertPool. -func NewTLSConfig(config *schema.TLSConfig, rootCAs *x509.CertPool) (tlsConfig *tls.Config) { +// NewTLSConfig generates a tls.Config from a schema.TLS and a x509.CertPool. +func NewTLSConfig(config *schema.TLS, rootCAs *x509.CertPool) (tlsConfig *tls.Config) { var certificates []tls.Certificate if config.PrivateKey != nil && config.CertificateChain.HasCertificates() {