Compare commits

..

1 Commits

Author SHA1 Message Date
James Elliott 65e9862f9f
docs: add json schema
Signed-off-by: James Elliott <james-d-elliott@users.noreply.github.com>
2023-06-18 17:59:46 +10:00
163 changed files with 9624 additions and 3984 deletions

View File

@ -7,4 +7,3 @@
!entrypoint.sh
!healthcheck.sh
!.healthcheck.env
!dist/public_html/

View File

@ -1,95 +0,0 @@
# Ausführen
Um die Anwendung lokal auszuführen, können die folgenden Befehle verwendet werden.
```
export GOPATH=/tmp
source bootstrap.sh
authelia-scripts suites setup Standalone
```
Nun sollte der "Haupt-Enpunkt" unter `https://home.example.com:8080` und die API unter `https://authelia.example.com:9091` erreichbar sein. Achtung: es wird ein selbstsigniertes Zertifikat verwendet!
Mithilfe der Hot-Reload kann jetzt gecoded werden.
---
Nach der Entwicklung kann die Testumgebung durch den folgenden Befehl wieder zurückgesetzt werden.
```
go run ./cmd/authelia-scripts/ suites teardown Standalone
```
## Benutzerdefinierte Zertifikate
Um ein benutzerdefiniertes Zertifikat für die Ausführung zu verwenden, muss die Datai `public.backend.crt` und `private.bakend.pem` unter [diesem](/internal/suites/common/pki/) Verzeichnis abgeändert werden.
Um die Gültigkeit zu testen, kann der folgendende Befehl ausgeführt werden.
```
curl https://auth.rpjosh.de:9091 --connect-to 'auth.rpjosh.de:9091:authelia.example.com:9091'
```
## Externe erreichbarkeit
Im aktuellen Zustand sind die Endpunkte nur unter den Docker internen IP-Adressen erreichbar. Daher muss noch ein NAT Regel angelegt werden.
```
ip=$(ping -c 1 authelia.example.com | gawk -F'[()]' '/PING/{print $2}')
sudo iptables -t nat -A PREROUTING -p tcp --dport 9091 -d 192.168.0.15 -j DNAT --to-destination 192.168.240.50:9091 -m comment --comment "Authelia-Test"
sudo iptables -t nat -A PREROUTING -p tcp --dport 9092 -d 192.168.0.15 -j DNAT --to-destination 192.168.240.50:9092 -m comment --comment "Authelia-Test"
sudo iptables -t nat -I OUTPUT -p tcp -o lo --dport 9091 -j DNAT --to-destination 192.168.240.50:9091
```
# Customizations
Für das Starten des *gRPC* Servers müssen die folgenden Abhängigkeiten installiert werden.
```
go get github.com/envoyproxy/go-control-plane
go get github.com/envoyproxy/go-control-plane/envoy/config/core/v3
go get github.com/gogo/googleapis/google/rpc
go get google.golang.org/grpc
```
## Konfiguration ändern
Wenn die Konfiguration geändert wurde, müssen die Keys zur Validierung wieder erneut gebaut werden.
```
go run ./cmd/authelia-gen code keys
```
## Mocks abgeändert
Wenn interfaces von den Mocks geändert werden, muss folgendes wieder ausgeführt werden:
```
export PATH=$PATH:$(go env GOPATH)/bin
go generate ./...
```
## Bauen
Um ein Docker Image für authelia zu bauen, müssen die folgenden Befehle ausgeführt werden.
```sh
# Dieser Befehle funktionieren aktuell nicht
authelia-scripts docker build
authelia-scripts build
# => Manuell bauen
export CC=musl-gcc
authelia-scripts build
cp -r dist/public_html internal/server/
go build -buildmode=pie -ldflags "-linkmode=external -s -w" -trimpath -buildmode=pie -o authelia ./cmd/authelia
mv authelia authelia-linux-amd64-musl
# Build docker image
docker build --tag git.rpjosh.de/rpjosh/authelia/authelia:4.38.0-dev .
docker push git.rpjosh.de/rpjosh/authelia/authelia:4.38.0-dev
# Cleanup
rm -rf internal/server/public_html/ ./authelia-linux-amd64-musl
```
# gRCP
Um einen gRCP Endpunkt nutzen zu können, brauch mein eine *.proto* Datei. Für Envoy sieht diese wie in [dieser Datei](/ext-auth.proto) folgendermaßen aus.

View File

@ -13,7 +13,7 @@ func newDocsCmd() *cobra.Command {
DisableAutoGenTag: true,
}
cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd())
cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd(), newDocsJSONSchemaCmd())
return cmd
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -90,7 +90,7 @@ func TestSortCmds(t *testing.T) {
{
"ShouldSortDocsCmd",
newDocsCmd(),
[]string{"cli", "data", "date"},
[]string{"cli", "data", "json-schema", "date"},
},
{
"ShouldSortGitHubCmd",

View File

@ -20,6 +20,8 @@ const (
dirDocs = "docs"
dirDocsContent = "content"
dirDocsStatic = "static"
dirDocsStaticJSONSchemas = "schemas"
dirDocsData = "data"
dirDocsCLIReference = "en/reference/cli"
@ -27,6 +29,9 @@ const (
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"
)
@ -75,12 +80,18 @@ const (
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"
@ -88,6 +99,8 @@ const (
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: ""},

View File

@ -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)

View File

@ -62,10 +62,6 @@ server:
## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
disable_healthcheck: false
## If a request over the insecure http protocol is received from authelias gRPC endpoint (only for envoy),
## the request is by default redirected to the matching https URL (301)
disable_autho_https_redirect: false
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls:
## The path to the DER base64/PEM format private key.
@ -77,17 +73,6 @@ server:
## The list of certificates for client authentication.
client_certificates: []
## Enable the support for gRPC ext authentication for envoy. If TLS is enabled in the above section,
## the defined certificates will also be used for the gRPC endpoint
grpc:
address: 'tcp://:9092'
# Even if TLS is configured in the server setting (under server.tls), the grcp server won't use TLS
disableTLS: false
# By default the ban is issued for the user. With this options the IP instead of the user will be banned
use_ip_for_ban: true
## Server headers configuration/customization.
headers:

View File

@ -24,12 +24,16 @@ authelia-gen [flags]
```
-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")
@ -39,12 +43,16 @@ authelia-gen [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen code [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen code [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen code keys [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen code keys [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen code scripts [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen code scripts [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen code server [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen code server [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen commit-lint [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen commit-lint [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen docs [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen docs [flags]
--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)
@ -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

View File

@ -30,12 +30,16 @@ authelia-gen docs cli [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen docs cli [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen docs data [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen docs data [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen docs data keys [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen docs data keys [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen docs data misc [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen docs data misc [flags]
--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)

View File

@ -32,12 +32,16 @@ authelia-gen docs date [flags]
```
-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")
@ -47,11 +51,15 @@ authelia-gen docs date [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen github [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen github [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen github issue-templates [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen github issue-templates [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen github issue-templates bug-report [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen github issue-templates bug-report [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen github issue-templates feature-request [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen github issue-templates feature-request [flags]
--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)

View File

@ -30,12 +30,16 @@ authelia-gen locales [flags]
```
-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")
@ -45,11 +49,15 @@ authelia-gen locales [flags]
--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)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -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.=\\/]+)$"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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.=\\/]+)$"
}
}
}

View File

@ -1,144 +0,0 @@
syntax = "proto3";
package envoy.service.auth.v3;
import "envoy/config/core/v3/base.proto";
import "envoy/service/auth/v3/attribute_context.proto";
import "envoy/type/v3/http_status.proto";
import "google/protobuf/struct.proto";
import "google/rpc/status.proto";
import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
option java_package = "io.envoyproxy.envoy.service.auth.v3";
option java_outer_classname = "ExternalAuthProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3;authv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Authorization service]
// The authorization service request messages used by external authorization :ref:`network filter
// <config_network_filters_ext_authz>` and :ref:`HTTP filter <config_http_filters_ext_authz>`.
// A generic interface for performing authorization check on incoming
// requests to a networked service.
service Authorization {
// Performs authorization check based on the attributes associated with the
// incoming request, and returns status `OK` or not `OK`.
rpc Check(CheckRequest) returns (CheckResponse) {
}
}
message CheckRequest {
option (udpa.annotations.versioning).previous_message_type = "envoy.service.auth.v2.CheckRequest";
// The request attributes.
AttributeContext attributes = 1;
}
// HTTP attributes for a denied response.
message DeniedHttpResponse {
option (udpa.annotations.versioning).previous_message_type =
"envoy.service.auth.v2.DeniedHttpResponse";
// This field allows the authorization service to send an HTTP response status code to the
// downstream client. If not set, Envoy sends ``403 Forbidden`` HTTP status code by default.
type.v3.HttpStatus status = 1;
// This field allows the authorization service to send HTTP response headers
// to the downstream client. Note that the :ref:`append field in HeaderValueOption <envoy_v3_api_field_config.core.v3.HeaderValueOption.append>` defaults to
// false when used in this message.
repeated config.core.v3.HeaderValueOption headers = 2;
// This field allows the authorization service to send a response body data
// to the downstream client.
string body = 3;
}
// HTTP attributes for an OK response.
// [#next-free-field: 9]
message OkHttpResponse {
option (udpa.annotations.versioning).previous_message_type =
"envoy.service.auth.v2.OkHttpResponse";
// HTTP entity headers in addition to the original request headers. This allows the authorization
// service to append, to add or to override headers from the original request before
// dispatching it to the upstream. Note that the :ref:`append field in HeaderValueOption <envoy_v3_api_field_config.core.v3.HeaderValueOption.append>` defaults to
// false when used in this message. By setting the ``append`` field to ``true``,
// the filter will append the correspondent header value to the matched request header.
// By leaving ``append`` as false, the filter will either add a new header, or override an existing
// one if there is a match.
repeated config.core.v3.HeaderValueOption headers = 2;
// HTTP entity headers to remove from the original request before dispatching
// it to the upstream. This allows the authorization service to act on auth
// related headers (like ``Authorization``), process them, and consume them.
// Under this model, the upstream will either receive the request (if it's
// authorized) or not receive it (if it's not), but will not see headers
// containing authorization credentials.
//
// Pseudo headers (such as ``:authority``, ``:method``, ``:path`` etc), as well as
// the header ``Host``, may not be removed as that would make the request
// malformed. If mentioned in ``headers_to_remove`` these special headers will
// be ignored.
//
// When using the HTTP service this must instead be set by the HTTP
// authorization service as a comma separated list like so:
// ``x-envoy-auth-headers-to-remove: one-auth-header, another-auth-header``.
repeated string headers_to_remove = 5;
// This field has been deprecated in favor of :ref:`CheckResponse.dynamic_metadata
// <envoy_v3_api_field_service.auth.v3.CheckResponse.dynamic_metadata>`. Until it is removed,
// setting this field overrides :ref:`CheckResponse.dynamic_metadata
// <envoy_v3_api_field_service.auth.v3.CheckResponse.dynamic_metadata>`.
google.protobuf.Struct dynamic_metadata = 3
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
// This field allows the authorization service to send HTTP response headers
// to the downstream client on success. Note that the :ref:`append field in HeaderValueOption <envoy_v3_api_field_config.core.v3.HeaderValueOption.append>`
// defaults to false when used in this message.
repeated config.core.v3.HeaderValueOption response_headers_to_add = 6;
// This field allows the authorization service to set (and overwrite) query
// string parameters on the original request before it is sent upstream.
repeated config.core.v3.QueryParameter query_parameters_to_set = 7;
// This field allows the authorization service to specify which query parameters
// should be removed from the original request before it is sent upstream. Each
// element in this list is a case-sensitive query parameter name to be removed.
repeated string query_parameters_to_remove = 8;
}
// Intended for gRPC and Network Authorization servers ``only``.
message CheckResponse {
option (udpa.annotations.versioning).previous_message_type =
"envoy.service.auth.v2.CheckResponse";
// Status ``OK`` allows the request. Any other status indicates the request should be denied, and
// for HTTP filter, if not overridden by :ref:`denied HTTP response status <envoy_v3_api_field_service.auth.v3.DeniedHttpResponse.status>`
// Envoy sends ``403 Forbidden`` HTTP status code by default.
google.rpc.Status status = 1;
// An message that contains HTTP response attributes. This message is
// used when the authorization service needs to send custom responses to the
// downstream client or, to modify/add request headers being dispatched to the upstream.
oneof http_response {
// Supplies http attributes for a denied response.
DeniedHttpResponse denied_response = 2;
// Supplies http attributes for an ok response.
OkHttpResponse ok_response = 3;
}
// Optional response metadata that will be emitted as dynamic metadata to be consumed by the next
// filter. This metadata lives in a namespace specified by the canonical name of extension filter
// that requires it:
//
// - :ref:`envoy.filters.http.ext_authz <config_http_filters_ext_authz_dynamic_metadata>` for HTTP filter.
// - :ref:`envoy.filters.network.ext_authz <config_network_filters_ext_authz_dynamic_metadata>` for network filter.
google.protobuf.Struct dynamic_metadata = 4;
}

View File

@ -45,7 +45,7 @@ services:
- TZ=Australia/Melbourne
traefik:
image: traefik:v2.10.3
image: traefik:v2.10.1
container_name: traefik
volumes:
- ./traefik:/etc/traefik

View File

@ -32,7 +32,7 @@ services:
- TZ=Australia/Melbourne
traefik:
image: traefik:v2.10.3
image: traefik:v2.10.1
container_name: traefik
volumes:
- ./traefik:/etc/traefik

28
go.mod
View File

@ -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
@ -20,7 +21,7 @@ require (
github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/jackc/pgx/v5 v5.4.1
github.com/jackc/pgx/v5 v5.4.0
github.com/jmoiron/sqlx v1.3.5
github.com/knadh/koanf/parsers/yaml v0.1.0
github.com/knadh/koanf/providers/confmap v0.1.0
@ -33,8 +34,8 @@ require (
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/ory/fosite v0.44.0
github.com/ory/herodot v0.10.2
github.com/ory/x v0.0.563
github.com/otiai10/copy v1.12.0
github.com/ory/x v0.0.561
github.com/otiai10/copy v1.11.0
github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.4.0
github.com/prometheus/client_golang v1.16.0
@ -43,7 +44,7 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/trustelem/zxcvbn v1.0.1
github.com/valyala/fasthttp v1.48.0
github.com/valyala/fasthttp v1.47.0
github.com/wneessen/go-mail v0.3.9
golang.org/x/net v0.11.0
golang.org/x/sync v0.3.0
@ -59,7 +60,6 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cristalhq/jwt/v4 v4.0.2 // indirect
github.com/dave/jennifer v1.6.0 // indirect
@ -69,21 +69,18 @@ require (
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/ecordell/optgen v0.0.6 // indirect
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-crypt/x v0.2.1 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-webauthn/revoke v0.1.9 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-tpm v0.3.3 // indirect
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
@ -102,7 +99,7 @@ require (
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/redis/go-redis/v9 v9.0.4 // indirect
@ -124,13 +121,12 @@ require (
github.com/ysmood/leakless v0.8.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e // indirect
google.golang.org/grpc v1.56.0 // indirect
google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd // indirect
google.golang.org/grpc v1.54.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

56
go.sum
View File

@ -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=
@ -72,8 +80,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@ -115,11 +121,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ=
github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/fasthttp/router v1.4.19 h1:RLE539IU/S4kfb4MP56zgP0TIBU9kEg0ID9GpWO0vqk=
@ -160,19 +162,13 @@ github.com/go-webauthn/revoke v0.1.9 h1:gSJ1ckA9VaKA2GN4Ukp+kiGTk1/EXtaDb1YE8Rkn
github.com/go-webauthn/revoke v0.1.9/go.mod h1:j6WKPnv0HovtEs++paan9g3ar46gm1NarktkXBaPR+w=
github.com/go-webauthn/webauthn v0.5.0 h1:Tbmp37AGIhYbQmcy2hEffo3U3cgPClqvxJ7cLUnF7Rc=
github.com/go-webauthn/webauthn v0.5.0/go.mod h1:0CBq/jNfPS9l033j4AxMk8K8MluiMsde9uGNSPFLEVE=
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -259,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=
@ -268,8 +266,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.4.1 h1:oKfB/FhuVtit1bBM3zNRRsZ925ZkMN3HXL+LgLUM9lE=
github.com/jackc/pgx/v5 v5.4.1/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY=
github.com/jackc/pgx/v5 v5.4.0 h1:BSr+GCm4N6QcgIwv0DyTFHK9ugfEFF9DzSbbzxOiXU0=
github.com/jackc/pgx/v5 v5.4.0/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY=
github.com/jandelgado/gcov2lcov v1.0.5 h1:rkBt40h0CVK4oCb8Dps950gvfd1rYvQ8+cWa346lVU0=
github.com/jandelgado/gcov2lcov v1.0.5/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
@ -279,7 +277,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
@ -344,10 +341,10 @@ github.com/ory/go-convenience v0.1.0 h1:zouLKfF2GoSGnJwGq+PE/nJAE6dj2Zj5QlTgmMTs
github.com/ory/go-convenience v0.1.0/go.mod h1:uEY/a60PL5c12nYz4V5cHY03IBmwIAEm8TWB0yn9KNs=
github.com/ory/herodot v0.10.2 h1:gGvNMHgAwWzdP/eo+roSiT5CGssygHSjDU7MSQNlJ4E=
github.com/ory/herodot v0.10.2/go.mod h1:MMNmY6MG1uB6fnXYFaHoqdV23DTWctlPsmRCeq/2+wc=
github.com/ory/x v0.0.563 h1:T77Bjt6ALMZmUJIsQ5UEkzDBCD+8vxfQlBCU1Y39uDk=
github.com/ory/x v0.0.563/go.mod h1:kup4ebSC4SzwU6KPZJ4G60UR3EEsHxJ0apQVflVw5yQ=
github.com/otiai10/copy v1.12.0 h1:cLMgSQnXBs1eehF0Wy/FAGsgDTDmAqFR7rQylBb1nDY=
github.com/otiai10/copy v1.12.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww=
github.com/ory/x v0.0.561 h1:SvNDGd6OhvAFl4XiPnYJuLCtR6iLxZJcF1Vzlo1IFTM=
github.com/ory/x v0.0.561/go.mod h1:kup4ebSC4SzwU6KPZJ4G60UR3EEsHxJ0apQVflVw5yQ=
github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc=
github.com/otiai10/copy v1.11.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww=
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
@ -376,8 +373,6 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
@ -451,8 +446,8 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.48.0 h1:oJWvHb9BIZToTQS3MuQ2R3bJZiNSa2KiNdeI8A+79Tc=
github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c=
github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/wneessen/go-mail v0.3.9 h1:Q4DbCk3htT5DtDWKeMgNXCiHc4bBY/vv/XQPT6XDXzc=
github.com/wneessen/go-mail v0.3.9/go.mod h1:zxOlafWCP/r6FEhAaRgH4IC1vg2YXxO0Nar9u0IScZ8=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
@ -594,10 +589,6 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -726,7 +717,6 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
@ -736,7 +726,6 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
@ -745,7 +734,6 @@ golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -815,10 +803,6 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd h1:sLpv7bNL1AsX3fdnWh9WVh7ejIzXdOc1RRHGeAmeStU=
google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw=
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e h1:NumxXLPfHSndr3wBBdeKiVHjGVFzi9RX2HwwQke94iY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@ -838,10 +822,6 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc v1.56.0 h1:+y7Bs8rtMd07LeXmL3NxcTLn7mUkbKZqEpPhMNkwJEE=
google.golang.org/grpc v1.56.0/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc/examples v0.0.0-20210304020650-930c79186c99 h1:qA8rMbz1wQ4DOFfM2ouD29DG9aHWBm6ZOy9BGxiUMmY=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

View File

@ -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(

View File

@ -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(),
// 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"`
// 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,

View File

@ -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)
}

View File

@ -10,7 +10,7 @@ import (
)
func TestDatabaseModel_Read(t *testing.T) {
model := &DatabaseModel{}
model := &FileDatabaseModel{}
dir := t.TempDir()

View File

@ -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,
}

View File

@ -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
}

View File

@ -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,
},
},

View File

@ -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

View File

@ -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},
},

View File

@ -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),

View File

@ -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<User>[a-zA-Z0-9]+)\.regex.com$`}),
Policy: oneFactor,
}).
WithRule(schema.ACLRule{
WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^group-(?P<Group>[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<User>[a-zA-Z0-9]+)/personal(/|/.*)?$`, `^/(?P<Group>[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,
},

View File

@ -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{}

View File

@ -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{

View File

@ -16,7 +16,6 @@ import (
"github.com/sirupsen/logrus"
"github.com/valyala/fasthttp"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/server"
@ -34,17 +33,6 @@ func NewServerService(name string, server *fasthttp.Server, listener net.Listene
}
}
// NewGRCPServerService creates a new ServerService with the appropriate logger etc.
func NewGRCPServerService(name string, server *grpc.Server, listener net.Listener, isTLS bool, log *logrus.Logger) (service *GRCPServerService) {
return &GRCPServerService{
name: name,
server: server,
listener: listener,
isTLS: isTLS,
log: log.WithFields(map[string]any{logFieldService: serviceTypeServer, serviceTypeServer: name}),
}
}
// NewFileWatcherService creates a new FileWatcherService with the appropriate logger etc.
func NewFileWatcherService(name, path string, reload ProviderReload, log *logrus.Logger) (service *FileWatcherService, err error) {
if path == "" {
@ -173,54 +161,6 @@ func (service *ServerService) Log() *logrus.Entry {
return service.log
}
// GRCPServerService is a Service which runs a gRCP server.
type GRCPServerService struct {
name string
server *grpc.Server
isTLS bool
listener net.Listener
log *logrus.Entry
}
// ServiceType returns the service type for this service, which is always 'server'.
func (service *GRCPServerService) ServiceType() string {
return serviceTypeServer
}
// ServiceName returns the individual name for this service.
func (service *GRCPServerService) ServiceName() string {
return service.name
}
// Run the ServerService.
func (service *GRCPServerService) Run() (err error) {
defer func() {
if r := recover(); r != nil {
service.log.WithError(recoverErr(r)).Error("Critical error caught (recovered)")
}
}()
service.log.Infof(fmtLogServerListening, connectionType(service.isTLS), service.listener.Addr().String())
if err = service.server.Serve(service.listener); err != nil {
service.log.WithError(err).Error("Error returned attempting to serve requests")
return err
}
return nil
}
// Shutdown the ServerService.
func (service *GRCPServerService) Shutdown() {
service.server.Stop()
}
// Log returns the *logrus.Entry of the ServerService.
func (service *GRCPServerService) Log() *logrus.Entry {
return service.log
}
// FileWatcherService is a Service that watches files for changes.
type FileWatcherService struct {
name string
@ -332,19 +272,6 @@ func svcSvrMetricsFunc(ctx *CmdCtx) (service Service) {
return service
}
func svcSvrGRPCFunc(ctx *CmdCtx) (service Service) {
switch svr, listener, isTLS, err := server.CreateGRPCServer(ctx.config, ctx.providers); {
case err != nil:
ctx.log.WithError(err).Fatal("Create Server Service (gRPC) returned error")
case svr != nil && listener != nil:
service = NewGRCPServerService("gRCP", svr, listener, isTLS, ctx.log)
default:
ctx.log.Debug("Create Server Service (gRPC) skipped")
}
return service
}
func svcWatcherUsersFunc(ctx *CmdCtx) (service Service) {
var err error
@ -385,7 +312,7 @@ func servicesRun(ctx *CmdCtx) {
)
for _, serviceFunc := range []func(ctx *CmdCtx) Service{
svcSvrMainFunc, svcSvrGRPCFunc, svcSvrMetricsFunc,
svcSvrMainFunc, svcSvrMetricsFunc,
svcWatcherUsersFunc,
} {
if service := serviceFunc(ctx); service != nil {

View File

@ -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 {

View File

@ -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",

View File

@ -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},
},
}

View File

@ -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"`
}

View File

@ -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"`
}

View File

@ -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"},

View File

@ -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",
@ -264,8 +264,6 @@ var Keys = []string{
"server.address",
"server.asset_path",
"server.disable_healthcheck",
"server.disable_autho_https_redirect",
"server.use_ip_for_ban",
"server.tls.certificate",
"server.tls.key",
"server.tls.client_certificates",
@ -276,8 +274,6 @@ var Keys = []string{
"server.endpoints.authz.*.implementation",
"server.endpoints.authz.*.authn_strategies",
"server.endpoints.authz.*.authn_strategies[].name",
"server.grpc.address",
"server.grpc.disableTLS",
"server.buffers.read",
"server.buffers.write",
"server.timeouts.read",

View File

@ -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",
}

View File

@ -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 <test@authelia.com>,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},
},
}

View File

@ -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,

View File

@ -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,
},
}

View File

@ -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"`
}

View File

@ -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,

View File

@ -5,75 +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"`
DisableAutoHttpsRedirect bool `koanf:"disable_autho_https_redirect"`
UseIPInsteadOfUserForBan bool `koanf:"use_ip_for_ban"`
// 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"`
GRPC ServerGRPC `koanf:"grpc"`
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"`
}
// ServerGRCP contains configuration options for the gRCP server.
type ServerGRPC struct {
// Address with port to listen on. If this field is empty, no grcp server
// will be spawned.
Address *AddressTCP `koanf:"address"`
DisableTLS bool `koanf:"disableTLS"`
}
// 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,
@ -85,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",
},
@ -102,7 +90,7 @@ var DefaultServerConfiguration = ServerConfiguration{
},
"forward-auth": {
Implementation: "ForwardAuth",
AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{
AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{
{
Name: "HeaderProxyAuthorization",
},
@ -113,7 +101,7 @@ var DefaultServerConfiguration = ServerConfiguration{
},
"ext-authz": {
Implementation: "ExtAuthz",
AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{
AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{
{
Name: "HeaderProxyAuthorization",
},

View File

@ -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},
},
}

View File

@ -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"`
}

View File

@ -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",
},
}

View File

@ -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,

View File

@ -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,

View File

@ -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
if d, err = cdecoder.Decode(encodedDigest); err != nil {
return nil, err
return cdecoder.Decode(encodedDigest)
}
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",
},
}

View File

@ -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

View File

@ -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,

View File

@ -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 == "" {

View File

@ -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<User>\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,
}

View File

@ -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"))

View File

@ -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)

View File

@ -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{
SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session",
Domain: exampleDotCom,
},
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'",

View File

@ -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",
},

View File

@ -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 == "" {

File diff suppressed because it is too large Load Diff

View File

@ -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",
},
}

View File

@ -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"))

View File

@ -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}),
}

View File

@ -11,7 +11,7 @@ import (
func newDefaultNTPConfig() schema.Configuration {
return schema.Configuration{
NTP: schema.NTPConfiguration{},
NTP: schema.NTP{},
}
}

View File

@ -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))
}

View File

@ -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,
},

View File

@ -11,7 +11,7 @@ import (
func newDefaultRegulationConfig() schema.Configuration {
config := schema.Configuration{
Regulation: schema.RegulationConfiguration{},
Regulation: schema.Regulation{},
}
return config

View File

@ -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 {

View File

@ -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": {},
}

View File

@ -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))
}

View File

@ -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,
},
},
{
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{
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{
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{
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{
config.Cookies = append(config.Cookies, schema.SessionCookie{
Domain: "internal.example.com",
},
AutheliaURL: MustParseURL("https://login.internal.example.com"),
})
@ -672,14 +671,12 @@ 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,
},
},
}
ValidateSession(&config, validator)
@ -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{
SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session",
Domain: exampleDotCom,
},
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)

View File

@ -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")
}

View File

@ -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))

View File

@ -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"))
}

View File

@ -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",
}

View File

@ -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'"},
},

View File

@ -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,

View File

@ -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

View File

@ -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"},

Some files were not shown because too many files have changed in this diff Show More