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 !entrypoint.sh
!healthcheck.sh !healthcheck.sh
!.healthcheck.env !.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, DisableAutoGenTag: true,
} }
cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd()) cmd.AddCommand(newDocsCLICmd(), newDocsDataCmd(), newDocsDateCmd(), newDocsJSONSchemaCmd())
return cmd 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.TemplateDefault = strings.ReplaceAll(data.CSP.TemplateDefault, "%s", codeCSPNonce)
data.CSP.TemplateDevelopment = strings.ReplaceAll(data.CSP.TemplateDevelopment, "%s", codeCSPNonce) data.CSP.TemplateDevelopment = strings.ReplaceAll(data.CSP.TemplateDevelopment, "%s", codeCSPNonce)
var ( version, err := readVersion(cmd)
pathPackageJSON string if err != nil {
dataPackageJSON []byte
packageJSON PackageJSON
)
if pathPackageJSON, err = getPFlagPath(cmd.Flags(), cmdFlagRoot, cmdFlagWeb, cmdFlagFileWebPackage); err != nil {
return err return err
} }
if dataPackageJSON, err = os.ReadFile(pathPackageJSON); err != nil { data.Latest = version.String()
return err
}
if err = json.Unmarshal(dataPackageJSON, &packageJSON); err != nil {
return fmt.Errorf("failed to unmarshall package.json: %w", err)
}
data.Latest = packageJSON.Version
var ( var (
outputPath string 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().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().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(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(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(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") 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(cmdFlagDocsCLIReference, dirDocsCLIReference, "The directory to store the markdown in")
cmd.PersistentFlags().String(cmdFlagDocs, dirDocs, "The directory with the docs") cmd.PersistentFlags().String(cmdFlagDocs, dirDocs, "The directory with the docs")
cmd.PersistentFlags().String(cmdFlagDocsContent, dirDocsContent, "The directory with the docs content") 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(cmdFlagDocsData, dirDocsData, "The directory with the docs data")
cmd.PersistentFlags().String(cmdFlagFileConfigKeys, fileCodeConfigKeys, "Sets the path of the keys file") 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(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(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(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(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(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(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().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()) cmd.AddCommand(newCodeCmd(), newDocsCmd(), newGitHubCmd(), newLocalesCmd(), newCommitLintCmd())
return cmd return cmd

View File

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

View File

@ -20,6 +20,8 @@ const (
dirDocs = "docs" dirDocs = "docs"
dirDocsContent = "content" dirDocsContent = "content"
dirDocsStatic = "static"
dirDocsStaticJSONSchemas = "schemas"
dirDocsData = "data" dirDocsData = "data"
dirDocsCLIReference = "en/reference/cli" dirDocsCLIReference = "en/reference/cli"
@ -27,6 +29,9 @@ const (
fileDocsDataMisc = "misc.json" fileDocsDataMisc = "misc.json"
fileDocsDataConfigKeys = "configkeys.json" fileDocsDataConfigKeys = "configkeys.json"
fileDocsStaticJSONSchemasConfiguration = "configuration.json"
fileDocsStaticJSONSchemasUserDatabase = "user-database.json"
fileGitHubIssueTemplateFR = ".github/ISSUE_TEMPLATE/feature-request.yml" fileGitHubIssueTemplateFR = ".github/ISSUE_TEMPLATE/feature-request.yml"
fileGitHubIssueTemplateBR = ".github/ISSUE_TEMPLATE/bug-report.yml" fileGitHubIssueTemplateBR = ".github/ISSUE_TEMPLATE/bug-report.yml"
) )
@ -75,12 +80,18 @@ const (
cmdFlagFileWebPackage = "file.web.package" cmdFlagFileWebPackage = "file.web.package"
cmdFlagDocs = "dir.docs" cmdFlagDocs = "dir.docs"
cmdFlagDirLocales = "dir.locales" cmdFlagDirLocales = "dir.locales"
cmdFlagDirSchema = "dir.schema"
cmdFlagDirAuthentication = "dir.authentication"
cmdFlagDocsCLIReference = "dir.docs.cli-reference" cmdFlagDocsCLIReference = "dir.docs.cli-reference"
cmdFlagDocsContent = "dir.docs.content" cmdFlagDocsContent = "dir.docs.content"
cmdFlagDocsStatic = "dir.docs.static"
cmdFlagDocsStaticJSONSchemas = "dir.docs.static.json-schemas"
cmdFlagDocsData = "dir.docs.data" cmdFlagDocsData = "dir.docs.data"
cmdFlagDocsDataMisc = "file.docs.data.misc" cmdFlagDocsDataMisc = "file.docs.data.misc"
cmdFlagDocsDataKeys = "file.docs.data.keys" cmdFlagDocsDataKeys = "file.docs.data.keys"
cmdFlagDocsDataLanguages = "file.docs.data.languages" cmdFlagDocsDataLanguages = "file.docs.data.languages"
cmdFlagDocsStaticJSONSchemaConfiguration = "file.docs.static.json-schemas.configuration"
cmdFlagDocsStaticJSONSchemaUserDatabase = "file.docs.static.json-schemas.user-database"
cmdFlagFileConfigKeys = "file.configuration-keys" cmdFlagFileConfigKeys = "file.configuration-keys"
cmdFlagFileScriptsGen = "file.scripts.gen" cmdFlagFileScriptsGen = "file.scripts.gen"
cmdFlagFileServerGenerated = "file.server.generated" cmdFlagFileServerGenerated = "file.server.generated"
@ -88,6 +99,8 @@ const (
cmdFlagFileDocsCommitMsgGuidelines = "file.docs-commit-msg-guidelines" cmdFlagFileDocsCommitMsgGuidelines = "file.docs-commit-msg-guidelines"
cmdFlagFeatureRequest = "file.feature-request" cmdFlagFeatureRequest = "file.feature-request"
cmdFlagBugReport = "file.bug-report" cmdFlagBugReport = "file.bug-report"
cmdFlagLatest = "latest"
cmdFlagNext = "next"
cmdFlagExclude = "exclude" cmdFlagExclude = "exclude"
cmdFlagVersions = "versions" cmdFlagVersions = "versions"
@ -102,6 +115,14 @@ const (
codeCSPNonce = "${NONCE}" codeCSPNonce = "${NONCE}"
) )
const (
goModuleBase = "github.com/authelia/authelia/v4"
)
const (
windows = "windows"
)
var ( var (
codeCSPValuesCommon = []CSPValue{ codeCSPValuesCommon = []CSPValue{
{Name: "default-src", Value: ""}, {Name: "default-src", Value: ""},

View File

@ -3,18 +3,22 @@ package main
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rsa" "crypto/rsa"
"encoding/json"
"fmt" "fmt"
"net/mail" "net/mail"
"net/url" "net/url"
"os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"strings" "strings"
"time" "time"
"github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/model"
) )
func getPFlagPath(flags *pflag.FlagSet, flagNames ...string) (fullPath string, err error) { 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 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 //nolint:gocyclo
func readTags(prefix string, t reflect.Type, envSkip bool) (tags []string) { func readTags(prefix string, t reflect.Type, envSkip bool) (tags []string) {
tags = make([]string, 0) 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. ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
disable_healthcheck: false 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. ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls: tls:
## The path to the DER base64/PEM format private key. ## The path to the DER base64/PEM format private key.
@ -77,17 +73,6 @@ server:
## The list of certificates for client authentication. ## The list of certificates for client authentication.
client_certificates: [] 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. ## Server headers configuration/customization.
headers: headers:

View File

@ -24,12 +24,16 @@ authelia-gen [flags]
``` ```
-C, --cwd string Sets the CWD for git commands -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --file.web.package string The node package configuration file in relation to the web directory (default "package.json")
-h, --help help for authelia-gen -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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 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 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 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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 -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 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.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.content string The directory with the docs content (default "content")
--dir.docs.data string The directory with the docs data (default "data") --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") --dir.locales string The locales directory in relation to the root (default "internal/server/locales")
-d, --dir.root string The repository root (default "./") -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") --dir.web string The repository web directory in relation to the root directory (default "web")
-X, --exclude strings Sets the names of excluded generators -X, --exclude strings Sets the names of excluded generators
--file.bug-report string Sets the path of the bug report issue template file (default ".github/ISSUE_TEMPLATE/bug-report.yml") --file.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.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.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.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.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.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.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.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") --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.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") --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) --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 - TZ=Australia/Melbourne
traefik: traefik:
image: traefik:v2.10.3 image: traefik:v2.10.1
container_name: traefik container_name: traefik
volumes: volumes:
- ./traefik:/etc/traefik - ./traefik:/etc/traefik

View File

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

28
go.mod
View File

@ -5,6 +5,7 @@ go 1.20
require ( require (
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4 github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d 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/deckarep/golang-set/v2 v2.3.0
github.com/duosecurity/duo_api_golang v0.0.0-20230418202038-096d3306c029 github.com/duosecurity/duo_api_golang v0.0.0-20230418202038-096d3306c029
github.com/fasthttp/router v1.4.19 github.com/fasthttp/router v1.4.19
@ -20,7 +21,7 @@ require (
github.com/golang/mock v1.6.0 github.com/golang/mock v1.6.0
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/hashicorp/go-retryablehttp v0.7.4 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/jmoiron/sqlx v1.3.5
github.com/knadh/koanf/parsers/yaml v0.1.0 github.com/knadh/koanf/parsers/yaml v0.1.0
github.com/knadh/koanf/providers/confmap 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/ory/fosite v0.44.0 github.com/ory/fosite v0.44.0
github.com/ory/herodot v0.10.2 github.com/ory/herodot v0.10.2
github.com/ory/x v0.0.563 github.com/ory/x v0.0.561
github.com/otiai10/copy v1.12.0 github.com/otiai10/copy v1.11.0
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.4.0 github.com/pquerna/otp v1.4.0
github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_golang v1.16.0
@ -43,7 +44,7 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/trustelem/zxcvbn v1.0.1 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 github.com/wneessen/go-mail v0.3.9
golang.org/x/net v0.11.0 golang.org/x/net v0.11.0
golang.org/x/sync v0.3.0 golang.org/x/sync v0.3.0
@ -59,7 +60,6 @@ require (
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/cespare/xxhash/v2 v2.2.0 // 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/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cristalhq/jwt/v4 v4.0.2 // indirect github.com/cristalhq/jwt/v4 v4.0.2 // indirect
github.com/dave/jennifer v1.6.0 // indirect github.com/dave/jennifer v1.6.0 // indirect
@ -69,21 +69,18 @@ require (
github.com/dlclark/regexp2 v1.4.0 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect
github.com/ecordell/optgen v0.0.6 // 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/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-crypt/x v0.2.1 // indirect github.com/go-crypt/x v0.2.1 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-webauthn/revoke v0.1.9 // indirect github.com/go-webauthn/revoke v0.1.9 // indirect
github.com/gogo/googleapis v1.4.1 // indirect github.com/golang/glog v1.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-tpm v0.3.3 // indirect github.com/google/go-tpm v0.3.3 // indirect
github.com/gorilla/websocket v1.5.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/hcl v1.0.0 // 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/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // 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/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/philhofer/fwd v1.1.2 // indirect github.com/philhofer/fwd v1.1.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // 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/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect github.com/prometheus/procfs v0.10.1 // indirect
github.com/redis/go-redis/v9 v9.0.4 // indirect github.com/redis/go-redis/v9 v9.0.4 // indirect
@ -124,13 +121,12 @@ require (
github.com/ysmood/leakless v0.8.0 // indirect github.com/ysmood/leakless v0.8.0 // indirect
golang.org/x/crypto v0.10.0 // indirect golang.org/x/crypto v0.10.0 // indirect
golang.org/x/mod 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/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/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e // indirect google.golang.org/grpc v1.54.0 // indirect
google.golang.org/grpc v1.56.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.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/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 h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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 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.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 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-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-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/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/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/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 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.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.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.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 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 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/fasthttp/router v1.4.19 h1:RLE539IU/S4kfb4MP56zgP0TIBU9kEg0ID9GpWO0vqk= 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/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 h1:Tbmp37AGIhYbQmcy2hEffo3U3cgPClqvxJ7cLUnF7Rc=
github.com/go-webauthn/webauthn v0.5.0/go.mod h1:0CBq/jNfPS9l033j4AxMk8K8MluiMsde9uGNSPFLEVE= 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.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.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 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 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 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 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= 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-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-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/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/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 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 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-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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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/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 h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= 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.0 h1:BSr+GCm4N6QcgIwv0DyTFHK9ugfEFF9DzSbbzxOiXU0=
github.com/jackc/pgx/v5 v5.4.1/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY= 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 h1:rkBt40h0CVK4oCb8Dps950gvfd1rYvQ8+cWa346lVU0=
github.com/jandelgado/gcov2lcov v1.0.5/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss= github.com/jandelgado/gcov2lcov v1.0.5/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= 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/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/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.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/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 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 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/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 h1:gGvNMHgAwWzdP/eo+roSiT5CGssygHSjDU7MSQNlJ4E=
github.com/ory/herodot v0.10.2/go.mod h1:MMNmY6MG1uB6fnXYFaHoqdV23DTWctlPsmRCeq/2+wc= 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.561 h1:SvNDGd6OhvAFl4XiPnYJuLCtR6iLxZJcF1Vzlo1IFTM=
github.com/ory/x v0.0.563/go.mod h1:kup4ebSC4SzwU6KPZJ4G60UR3EEsHxJ0apQVflVw5yQ= github.com/ory/x v0.0.561/go.mod h1:kup4ebSC4SzwU6KPZJ4G60UR3EEsHxJ0apQVflVw5yQ=
github.com/otiai10/copy v1.12.0 h1:cLMgSQnXBs1eehF0Wy/FAGsgDTDmAqFR7rQylBb1nDY= github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc=
github.com/otiai10/copy v1.12.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= 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/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 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 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.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 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= 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.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.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= 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/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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 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.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c=
github.com/valyala/fasthttp v1.48.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= 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 h1:Q4DbCk3htT5DtDWKeMgNXCiHc4bBY/vv/XQPT6XDXzc=
github.com/wneessen/go-mail v0.3.9/go.mod h1:zxOlafWCP/r6FEhAaRgH4IC1vg2YXxO0Nar9u0IScZ8= github.com/wneessen/go-mail v0.3.9/go.mod h1:zxOlafWCP/r6FEhAaRgH4IC1vg2YXxO0Nar9u0IScZ8=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 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.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 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= 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-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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-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-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-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-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-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/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-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-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-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.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.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= 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.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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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-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 h1:sLpv7bNL1AsX3fdnWh9WVh7ejIzXdOc1RRHGeAmeStU=
google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= 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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 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.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= 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.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/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-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 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. // FileUserProvider is a provider reading details from a file.
type FileUserProvider struct { type FileUserProvider struct {
config *schema.FileAuthenticationBackend config *schema.AuthenticationBackendFile
hash algorithm.Hash hash algorithm.Hash
database FileUserDatabase database FileUserProviderDatabase
mutex *sync.Mutex mutex *sync.Mutex
timeoutReload time.Time timeoutReload time.Time
} }
// NewFileUserProvider creates a new instance of FileUserProvider. // NewFileUserProvider creates a new instance of FileUserProvider.
func NewFileUserProvider(config *schema.FileAuthenticationBackend) (provider *FileUserProvider) { func NewFileUserProvider(config *schema.AuthenticationBackendFile) (provider *FileUserProvider) {
return &FileUserProvider{ return &FileUserProvider{
config: config, config: config,
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
timeoutReload: time.Now().Add(-1 * time.Second), 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. // CheckUserPassword checks if provided password matches for the given user.
func (p *FileUserProvider) CheckUserPassword(username string, password string) (match bool, err error) { 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 { if details, err = p.database.GetUserDetails(username); err != nil {
return false, err return false, err
@ -76,12 +76,12 @@ func (p *FileUserProvider) CheckUserPassword(username string, password string) (
return false, ErrUserNotFound return false, ErrUserNotFound
} }
return details.Digest.MatchAdvanced(password) return details.Password.MatchAdvanced(password)
} }
// GetDetails retrieve the groups a user belongs to. // GetDetails retrieve the groups a user belongs to.
func (p *FileUserProvider) GetDetails(username string) (details *UserDetails, err error) { 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 { if d, err = p.database.GetUserDetails(username); err != nil {
return nil, err return nil, err
@ -96,7 +96,7 @@ func (p *FileUserProvider) GetDetails(username string) (details *UserDetails, er
// UpdatePassword update the password of the given user. // UpdatePassword update the password of the given user.
func (p *FileUserProvider) UpdatePassword(username string, newPassword string) (err error) { 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 { if details, err = p.database.GetUserDetails(username); err != nil {
return err return err
@ -106,10 +106,14 @@ func (p *FileUserProvider) UpdatePassword(username string, newPassword string) (
return ErrUserNotFound 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 return err
} }
details.Password = schema.NewPasswordDigest(digest)
p.database.SetUserDetails(details.Username, &details) p.database.SetUserDetails(details.Username, &details)
p.mutex.Lock() p.mutex.Lock()
@ -138,7 +142,7 @@ func (p *FileUserProvider) StartupCheck() (err error) {
} }
if p.database == nil { 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 { 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. // 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 { switch config.Algorithm {
case hashArgon2, "": case hashArgon2, "":
hash, err = argon2.New( hash, err = argon2.New(

View File

@ -10,21 +10,23 @@ import (
"github.com/go-crypt/crypt" "github.com/go-crypt/crypt"
"github.com/go-crypt/crypt/algorithm" "github.com/go-crypt/crypt/algorithm"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/authelia/authelia/v4/internal/configuration/schema"
) )
type FileUserDatabase interface { type FileUserProviderDatabase interface {
Save() (err error) Save() (err error)
Load() (err error) Load() (err error)
GetUserDetails(username string) (user DatabaseUserDetails, err error) GetUserDetails(username string) (user FileUserDatabaseUserDetails, err error)
SetUserDetails(username string, details *DatabaseUserDetails) SetUserDetails(username string, details *FileUserDatabaseUserDetails)
} }
// NewYAMLUserDatabase creates a new YAMLUserDatabase. // NewFileUserDatabase creates a new FileUserDatabase.
func NewYAMLUserDatabase(filePath string, searchEmail, searchCI bool) (database *YAMLUserDatabase) { func NewFileUserDatabase(filePath string, searchEmail, searchCI bool) (database *FileUserDatabase) {
return &YAMLUserDatabase{ return &FileUserDatabase{
RWMutex: &sync.RWMutex{}, RWMutex: &sync.RWMutex{},
Path: filePath, Path: filePath,
Users: map[string]DatabaseUserDetails{}, Users: map[string]FileUserDatabaseUserDetails{},
Emails: map[string]string{}, Emails: map[string]string{},
Aliases: map[string]string{}, Aliases: map[string]string{},
SearchEmail: searchEmail, 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. // FileUserDatabase is a user details database that is concurrency safe database and can be reloaded.
type YAMLUserDatabase struct { type FileUserDatabase struct {
*sync.RWMutex *sync.RWMutex `json:"-"`
Path string Users map[string]FileUserDatabaseUserDetails `json:"users" jsonschema:"required,title=Users" jsonschema_description:"The dictionary of users"`
Users map[string]DatabaseUserDetails
Emails map[string]string
Aliases map[string]string
SearchEmail bool Path string `json:"-"`
SearchCI bool Emails map[string]string `json:"-"`
Aliases map[string]string `json:"-"`
SearchEmail bool `json:"-"`
SearchCI bool `json:"-"`
} }
// Save the database to disk. // Save the database to disk.
func (m *YAMLUserDatabase) Save() (err error) { func (m *FileUserDatabase) Save() (err error) {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
@ -59,8 +62,8 @@ func (m *YAMLUserDatabase) Save() (err error) {
} }
// Load the database from disk. // Load the database from disk.
func (m *YAMLUserDatabase) Load() (err error) { func (m *FileUserDatabase) Load() (err error) {
yml := &DatabaseModel{Users: map[string]UserDetailsModel{}} yml := &FileDatabaseModel{Users: map[string]FileDatabaseUserDetailsModel{}}
if err = yml.Read(m.Path); err != nil { if err = yml.Read(m.Path); err != nil {
return fmt.Errorf("error reading the authentication database: %w", err) 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. // 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 { if m.SearchEmail || m.SearchCI {
for k, user := range m.Users { for k, user := range m.Users {
if m.SearchEmail && user.Email != "" { if m.SearchEmail && user.Email != "" {
@ -98,7 +101,7 @@ func (m *YAMLUserDatabase) LoadAliases() (err error) {
return nil return nil
} }
func (m *YAMLUserDatabase) loadAlias(k string) (err error) { func (m *FileUserDatabase) loadAlias(k string) (err error) {
u := strings.ToLower(k) u := strings.ToLower(k)
if u != k { if u != k {
@ -120,7 +123,7 @@ func (m *YAMLUserDatabase) loadAlias(k string) (err error) {
return nil 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) e := strings.ToLower(user.Email)
var duplicates []string var duplicates []string
@ -150,9 +153,9 @@ func (m *YAMLUserDatabase) loadAliasEmail(k string, user DatabaseUserDetails) (e
return nil 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. // username.
func (m *YAMLUserDatabase) GetUserDetails(username string) (user DatabaseUserDetails, err error) { func (m *FileUserDatabase) GetUserDetails(username string) (user FileUserDatabaseUserDetails, err error) {
m.RLock() m.RLock()
defer m.RUnlock() defer m.RUnlock()
@ -178,8 +181,8 @@ func (m *YAMLUserDatabase) GetUserDetails(username string) (user DatabaseUserDet
return user, ErrUserNotFound return user, ErrUserNotFound
} }
// SetUserDetails sets the DatabaseUserDetails for a given user. // SetUserDetails sets the FileUserDatabaseUserDetails for a given user.
func (m *YAMLUserDatabase) SetUserDetails(username string, details *DatabaseUserDetails) { func (m *FileUserDatabase) SetUserDetails(username string, details *FileUserDatabaseUserDetails) {
if details == nil { if details == nil {
return return
} }
@ -191,10 +194,10 @@ func (m *YAMLUserDatabase) SetUserDetails(username string, details *DatabaseUser
m.Unlock() m.Unlock()
} }
// ToDatabaseModel converts the YAMLUserDatabase into the DatabaseModel for saving. // ToDatabaseModel converts the FileUserDatabase into the FileDatabaseModel for saving.
func (m *YAMLUserDatabase) ToDatabaseModel() (model *DatabaseModel) { func (m *FileUserDatabase) ToDatabaseModel() (model *FileDatabaseModel) {
model = &DatabaseModel{ model = &FileDatabaseModel{
Users: map[string]UserDetailsModel{}, Users: map[string]FileDatabaseUserDetailsModel{},
} }
m.RLock() m.RLock()
@ -208,18 +211,18 @@ func (m *YAMLUserDatabase) ToDatabaseModel() (model *DatabaseModel) {
return model return model
} }
// DatabaseUserDetails is the model of user details in the file database. // FileUserDatabaseUserDetails is the model of user details in the file database.
type DatabaseUserDetails struct { type FileUserDatabaseUserDetails struct {
Username string Username string `json:"-"`
Digest algorithm.Digest Password *schema.PasswordDigest `json:"password" jsonschema:"required,title=Password" jsonschema_description:"The hashed password for the user"`
Disabled bool DisplayName string `json:"displayname" jsonschema:"required,title=Display Name" jsonschema_description:"The display name for the user"`
DisplayName string Email string `json:"email" jsonschema:"title=Email" jsonschema_description:"The email for the user"`
Email string Groups []string `json:"groups" jsonschema:"title=Groups" jsonschema_description:"The groups list for the user"`
Groups []string 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. // ToUserDetails converts FileUserDatabaseUserDetails into a *UserDetails given a username.
func (m DatabaseUserDetails) ToUserDetails() (details *UserDetails) { func (m FileUserDatabaseUserDetails) ToUserDetails() (details *UserDetails) {
return &UserDetails{ return &UserDetails{
Username: m.Username, Username: m.Username,
DisplayName: m.DisplayName, DisplayName: m.DisplayName,
@ -228,26 +231,26 @@ func (m DatabaseUserDetails) ToUserDetails() (details *UserDetails) {
} }
} }
// ToUserDetailsModel converts DatabaseUserDetails into a UserDetailsModel. // ToUserDetailsModel converts FileUserDatabaseUserDetails into a FileDatabaseUserDetailsModel.
func (m DatabaseUserDetails) ToUserDetailsModel() (model UserDetailsModel) { func (m FileUserDatabaseUserDetails) ToUserDetailsModel() (model FileDatabaseUserDetailsModel) {
return UserDetailsModel{ return FileDatabaseUserDetailsModel{
HashedPassword: m.Digest.Encode(), Password: m.Password.Encode(),
DisplayName: m.DisplayName, DisplayName: m.DisplayName,
Email: m.Email, Email: m.Email,
Groups: m.Groups, Groups: m.Groups,
} }
} }
// DatabaseModel is the model of users file database. // FileDatabaseModel is the model of users file database.
type DatabaseModel struct { type FileDatabaseModel struct {
Users map[string]UserDetailsModel `yaml:"users" valid:"required"` 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. // ReadToFileUserDatabase reads the FileDatabaseModel into a FileUserDatabase.
func (m *DatabaseModel) ReadToFileUserDatabase(db *YAMLUserDatabase) (err error) { func (m *FileDatabaseModel) ReadToFileUserDatabase(db *FileUserDatabase) (err error) {
users := map[string]DatabaseUserDetails{} users := map[string]FileUserDatabaseUserDetails{}
var udm *DatabaseUserDetails var udm *FileUserDatabaseUserDetails
for user, details := range m.Users { for user, details := range m.Users {
if udm, err = details.ToDatabaseUserDetailsModel(user); err != nil { if udm, err = details.ToDatabaseUserDetailsModel(user); err != nil {
@ -262,8 +265,8 @@ func (m *DatabaseModel) ReadToFileUserDatabase(db *YAMLUserDatabase) (err error)
return nil return nil
} }
// Read a DatabaseModel from disk. // Read a FileDatabaseModel from disk.
func (m *DatabaseModel) Read(filePath string) (err error) { func (m *FileDatabaseModel) Read(filePath string) (err error) {
var ( var (
content []byte content []byte
ok bool ok bool
@ -292,8 +295,8 @@ func (m *DatabaseModel) Read(filePath string) (err error) {
return nil return nil
} }
// Write a DatabaseModel to disk. // Write a FileDatabaseModel to disk.
func (m *DatabaseModel) Write(fileName string) (err error) { func (m *FileDatabaseModel) Write(fileName string) (err error) {
var ( var (
data []byte data []byte
) )
@ -305,26 +308,26 @@ func (m *DatabaseModel) Write(fileName string) (err error) {
return os.WriteFile(fileName, data, fileAuthenticationMode) return os.WriteFile(fileName, data, fileAuthenticationMode)
} }
// UserDetailsModel is the model of user details in the file database. // FileDatabaseUserDetailsModel is the model of user details in the file database.
type UserDetailsModel struct { type FileDatabaseUserDetailsModel struct {
HashedPassword string `yaml:"password" valid:"required"` Password string `yaml:"password" valid:"required"`
DisplayName string `yaml:"displayname" valid:"required"` DisplayName string `yaml:"displayname" valid:"required"`
Email string `yaml:"email"` Email string `yaml:"email"`
Groups []string `yaml:"groups"` Groups []string `yaml:"groups"`
Disabled bool `yaml:"disabled"` Disabled bool `yaml:"disabled"`
} }
// ToDatabaseUserDetailsModel converts a UserDetailsModel into a *DatabaseUserDetails. // ToDatabaseUserDetailsModel converts a FileDatabaseUserDetailsModel into a *FileUserDatabaseUserDetails.
func (m UserDetailsModel) ToDatabaseUserDetailsModel(username string) (model *DatabaseUserDetails, err error) { func (m FileDatabaseUserDetailsModel) ToDatabaseUserDetailsModel(username string) (model *FileUserDatabaseUserDetails, err error) {
var d algorithm.Digest 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 nil, err
} }
return &DatabaseUserDetails{ return &FileUserDatabaseUserDetails{
Username: username, Username: username,
Digest: d, Password: schema.NewPasswordDigest(d),
Disabled: m.Disabled, Disabled: m.Disabled,
DisplayName: m.DisplayName, DisplayName: m.DisplayName,
Email: m.Email, Email: m.Email,

View File

@ -1,5 +1,5 @@
// Code generated by MockGen. DO NOT EDIT. // 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 is a generated GoMock package.
package authentication package authentication
@ -10,7 +10,7 @@ import (
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
) )
// MockFileUserDatabase is a mock of FileUserDatabase interface. // MockFileUserDatabase is a mock of FileUserProviderDatabase interface.
type MockFileUserDatabase struct { type MockFileUserDatabase struct {
ctrl *gomock.Controller ctrl *gomock.Controller
recorder *MockFileUserDatabaseMockRecorder recorder *MockFileUserDatabaseMockRecorder
@ -34,10 +34,10 @@ func (m *MockFileUserDatabase) EXPECT() *MockFileUserDatabaseMockRecorder {
} }
// GetUserDetails mocks base method. // GetUserDetails mocks base method.
func (m *MockFileUserDatabase) GetUserDetails(arg0 string) (DatabaseUserDetails, error) { func (m *MockFileUserDatabase) GetUserDetails(arg0 string) (FileUserDatabaseUserDetails, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserDetails", arg0) ret := m.ctrl.Call(m, "GetUserDetails", arg0)
ret0, _ := ret[0].(DatabaseUserDetails) ret0, _ := ret[0].(FileUserDatabaseUserDetails)
ret1, _ := ret[1].(error) ret1, _ := ret[1].(error)
return ret0, ret1 return ret0, ret1
} }
@ -77,7 +77,7 @@ func (mr *MockFileUserDatabaseMockRecorder) Save() *gomock.Call {
} }
// SetUserDetails mocks base method. // 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.T.Helper()
m.ctrl.Call(m, "SetUserDetails", arg0, arg1) m.ctrl.Call(m, "SetUserDetails", arg0, arg1)
} }

View File

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

View File

@ -49,7 +49,7 @@ func TestShouldErrorFailCreateDB(t *testing.T) {
f := filepath.Join(dir, "x", "users.yml") 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) require.NotNil(t, provider)
@ -70,7 +70,7 @@ func TestShouldErrorBadPasswordConfig(t *testing.T) {
require.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600)) require.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600))
provider := NewFileUserProvider(&schema.FileAuthenticationBackend{Path: f}) provider := NewFileUserProvider(&schema.AuthenticationBackendFile{Path: f})
require.NotNil(t, provider) require.NotNil(t, provider)
@ -85,7 +85,7 @@ func TestShouldNotPanicOnNilDB(t *testing.T) {
assert.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600)) assert.NoError(t, os.WriteFile(f, UserDatabaseContent, 0600))
provider := &FileUserProvider{ provider := &FileUserProvider{
config: &schema.FileAuthenticationBackend{Path: f, Password: schema.DefaultPasswordConfig}, config: &schema.AuthenticationBackendFile{Path: f, Password: schema.DefaultPasswordConfig},
mutex: &sync.Mutex{}, mutex: &sync.Mutex{},
timeoutReload: time.Now().Add(-1 * time.Second), timeoutReload: time.Now().Add(-1 * time.Second),
} }
@ -130,7 +130,7 @@ func TestShouldReloadDatabase(t *testing.T) {
provider.config.Path = p 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, false,
"", "",
@ -141,7 +141,7 @@ func TestShouldReloadDatabase(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
provider := NewFileUserProvider(&schema.FileAuthenticationBackend{ provider := NewFileUserProvider(&schema.AuthenticationBackendFile{
Path: path, Path: path,
Password: schema.DefaultPasswordConfig, Password: schema.DefaultPasswordConfig,
}) })
@ -307,10 +307,10 @@ func TestShouldUpdatePasswordHashingAlgorithmToArgon2id(t *testing.T) {
assert.NoError(t, provider.StartupCheck()) assert.NoError(t, provider.StartupCheck())
db, ok := provider.database.(*YAMLUserDatabase) db, ok := provider.database.(*FileUserDatabase)
require.True(t, ok) 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") err := provider.UpdatePassword("harry", "newpassword")
assert.NoError(t, err) assert.NoError(t, err)
@ -322,7 +322,7 @@ func TestShouldUpdatePasswordHashingAlgorithmToArgon2id(t *testing.T) {
ok, err = provider.CheckUserPassword("harry", "newpassword") ok, err = provider.CheckUserPassword("harry", "newpassword")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, ok) 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()) assert.NoError(t, provider.StartupCheck())
db, ok := provider.database.(*YAMLUserDatabase) db, ok := provider.database.(*FileUserDatabase)
require.True(t, ok) 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") err := provider.UpdatePassword("john", "newpassword")
assert.NoError(t, err) assert.NoError(t, err)
@ -352,7 +352,7 @@ func TestShouldUpdatePasswordHashingAlgorithmToSHA512(t *testing.T) {
ok, err = provider.CheckUserPassword("john", "newpassword") ok, err = provider.CheckUserPassword("john", "newpassword")
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, ok) 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) 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) { func TestNewFileCryptoHashFromConfig(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have schema.Password have schema.AuthenticationBackendFilePassword
expected any expected any
err string err string
}{ }{
{ {
"ShouldCreatePBKDF2", "ShouldCreatePBKDF2",
schema.Password{ schema.AuthenticationBackendFilePassword{
Algorithm: "pbkdf2", Algorithm: "pbkdf2",
PBKDF2: schema.PBKDF2Password{ PBKDF2: schema.AuthenticationBackendFilePasswordPBKDF2{
Variant: "sha256", Variant: "sha256",
Iterations: 100000, Iterations: 100000,
SaltLength: 16, SaltLength: 16,
@ -605,9 +605,9 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) {
}, },
{ {
"ShouldCreateSCrypt", "ShouldCreateSCrypt",
schema.Password{ schema.AuthenticationBackendFilePassword{
Algorithm: "scrypt", Algorithm: "scrypt",
SCrypt: schema.SCryptPassword{ SCrypt: schema.AuthenticationBackendFilePasswordSCrypt{
Iterations: 12, Iterations: 12,
SaltLength: 16, SaltLength: 16,
Parallelism: 1, Parallelism: 1,
@ -620,9 +620,9 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) {
}, },
{ {
"ShouldCreateBCrypt", "ShouldCreateBCrypt",
schema.Password{ schema.AuthenticationBackendFilePassword{
Algorithm: "bcrypt", Algorithm: "bcrypt",
BCrypt: schema.BCryptPassword{ BCrypt: schema.AuthenticationBackendFilePasswordBCrypt{
Variant: "standard", Variant: "standard",
Cost: 12, Cost: 12,
}, },
@ -632,7 +632,7 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) {
}, },
{ {
"ShouldFailToCreateSCryptInvalidParameter", "ShouldFailToCreateSCryptInvalidParameter",
schema.Password{ schema.AuthenticationBackendFilePassword{
Algorithm: "scrypt", Algorithm: "scrypt",
}, },
nil, nil,
@ -640,7 +640,7 @@ func TestNewFileCryptoHashFromConfig(t *testing.T) {
}, },
{ {
"ShouldFailUnknown", "ShouldFailUnknown",
schema.Password{ schema.AuthenticationBackendFilePassword{
Algorithm: "unknown", Algorithm: "unknown",
}, },
nil, nil,
@ -688,7 +688,7 @@ func TestHashError(t *testing.T) {
func TestDatabaseError(t *testing.T) { func TestDatabaseError(t *testing.T) {
WithDatabase(t, UserDatabaseContent, func(path string) { WithDatabase(t, UserDatabaseContent, func(path string) {
db := NewYAMLUserDatabase(path, false, false) db := NewFileUserDatabase(path, false, false)
assert.NoError(t, db.Load()) assert.NoError(t, db.Load())
config := DefaultFileAuthenticationBackendConfiguration config := DefaultFileAuthenticationBackendConfiguration
@ -717,7 +717,7 @@ func TestDatabaseError(t *testing.T) {
} }
var ( var (
DefaultFileAuthenticationBackendConfiguration = schema.FileAuthenticationBackend{ DefaultFileAuthenticationBackendConfiguration = schema.AuthenticationBackendFile{
Path: "", Path: "",
Password: schema.DefaultCIPasswordConfig, 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. // LDAPUserProvider is a UserProvider that connects to LDAP servers like ActiveDirectory, OpenLDAP, OpenDJ, FreeIPA, etc.
type LDAPUserProvider struct { type LDAPUserProvider struct {
config schema.LDAPAuthenticationBackend config schema.AuthenticationBackendLDAP
tlsConfig *tls.Config tlsConfig *tls.Config
dialOpts []ldap.DialOpt dialOpts []ldap.DialOpt
log *logrus.Logger 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. // 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 { if config.TLS == nil {
config.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS config.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom.TLS
} }

View File

@ -17,13 +17,13 @@ import (
) )
func TestNewLDAPUserProvider(t *testing.T) { 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) assert.NotNil(t, provider)
} }
func TestNewLDAPUserProviderWithFactoryWithoutFactory(t *testing.T) { func TestNewLDAPUserProviderWithFactoryWithoutFactory(t *testing.T) {
provider := NewLDAPUserProviderWithFactory(schema.LDAPAuthenticationBackend{}, false, nil, nil) provider := NewLDAPUserProviderWithFactory(schema.AuthenticationBackendLDAP{}, false, nil, nil)
assert.NotNil(t, provider) assert.NotNil(t, provider)
@ -38,7 +38,7 @@ func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
@ -70,7 +70,7 @@ func TestShouldCreateTLSConnectionWhenSchemeIsLDAPS(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPSAddress, Address: testLDAPSAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
@ -120,7 +120,7 @@ func TestEscapeSpecialCharsInGroupsFilter(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl) mockFactory := NewMockLDAPClientFactory(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPSAddress, Address: testLDAPSAddress,
GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))", GroupsFilter: "(|(member={dn})(uid={username})(uid={input}))",
}, },
@ -150,23 +150,23 @@ func TestResolveGroupsFilter(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have schema.LDAPAuthenticationBackend have schema.AuthenticationBackendLDAP
input string input string
profile ldapUserProfile profile ldapUserProfile
expected string expected string
}{ }{
{ {
"ShouldResolveEmptyFilter", "ShouldResolveEmptyFilter",
schema.LDAPAuthenticationBackend{}, schema.AuthenticationBackendLDAP{},
"", "",
ldapUserProfile{}, ldapUserProfile{},
"", "",
}, },
{ {
"ShouldResolveMemberOfRDNFilter", "ShouldResolveMemberOfRDNFilter",
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
GroupsFilter: "(|{memberof:rdn})", GroupsFilter: "(|{memberof:rdn})",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
GroupName: "cn", GroupName: "cn",
MemberOf: "memberOf", MemberOf: "memberOf",
@ -183,9 +183,9 @@ func TestResolveGroupsFilter(t *testing.T) {
}, },
{ {
"ShouldResolveMemberOfDNFilter", "ShouldResolveMemberOfDNFilter",
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
GroupsFilter: "(|{memberof:dn})", GroupsFilter: "(|{memberof:dn})",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
GroupName: "cn", GroupName: "cn",
MemberOf: "memberOf", MemberOf: "memberOf",
@ -246,7 +246,7 @@ func (e *ExtendedSearchRequestMatcher) String() string {
func TestShouldCheckLDAPEpochFilters(t *testing.T) { func TestShouldCheckLDAPEpochFilters(t *testing.T) {
type have struct { type have struct {
users string users string
attr schema.LDAPAuthenticationAttributes attr schema.AuthenticationBackendLDAPAttributes
} }
type expected struct { type expected struct {
@ -302,7 +302,7 @@ func TestShouldCheckLDAPEpochFilters(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
UsersFilter: tc.have.users, UsersFilter: tc.have.users,
Attributes: tc.have.attr, Attributes: tc.have.attr,
BaseDN: "dc=example,dc=com", BaseDN: "dc=example,dc=com",
@ -326,11 +326,11 @@ func TestShouldCheckLDAPServerExtensions(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -394,11 +394,11 @@ func TestShouldNotCheckLDAPServerExtensionsWhenRootDSEReturnsMoreThanOneEntry(t
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -463,11 +463,11 @@ func TestShouldCheckLDAPServerControlTypes(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -531,11 +531,11 @@ func TestShouldNotEnablePasswdModifyExtensionOrControlTypes(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -599,11 +599,11 @@ func TestShouldReturnCheckServerConnectError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -635,11 +635,11 @@ func TestShouldReturnCheckServerSearchError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -683,12 +683,12 @@ func TestShouldPermitRootDSEFailure(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
PermitFeatureDetectionFailure: true, PermitFeatureDetectionFailure: true,
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -747,11 +747,11 @@ func TestShouldEscapeUserInput(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))", UsersFilter: "(|({username_attribute}={input})({mail_attribute}={input}))",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -784,11 +784,11 @@ func TestShouldReturnEmailWhenAttributeSameAsUsername(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "mail", Username: "mail",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -858,11 +858,11 @@ func TestShouldReturnUsernameAndBlankDisplayNameWhenAttributesTheSame(t *testing
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "uid", DisplayName: "uid",
@ -932,11 +932,11 @@ func TestShouldReturnBlankEmailAndDisplayNameWhenAttrsLenZero(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1013,12 +1013,12 @@ func TestShouldCombineUsernameFilterAndUsersFilter(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
UsersFilter: "(&({username_attribute}={input})(&(objectCategory=person)(objectClass=user)))", UsersFilter: "(&({username_attribute}={input})(&(objectCategory=person)(objectClass=user)))",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1092,11 +1092,11 @@ func TestShouldNotCrashWhenGroupsAreNotRetrievedFromLDAP(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1169,11 +1169,11 @@ func TestLDAPUserProvider_GetDetails_ShouldReturnOnUserError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1217,11 +1217,11 @@ func TestLDAPUserProvider_GetDetails_ShouldReturnOnGroupsError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1290,11 +1290,11 @@ func TestShouldNotCrashWhenEmailsAreNotRetrievedFromLDAP(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
DisplayName: "displayName", DisplayName: "displayName",
MemberOf: "memberOf", MemberOf: "memberOf",
@ -1356,11 +1356,11 @@ func TestShouldUnauthenticatedBind(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "", Password: "",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
DisplayName: "displayName", DisplayName: "displayName",
MemberOf: "memberOf", MemberOf: "memberOf",
@ -1422,11 +1422,11 @@ func TestShouldReturnUsernameFromLDAP(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1498,11 +1498,11 @@ func TestShouldReturnUsernameFromLDAPSearchModeMemberOfRDN(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -1588,11 +1588,11 @@ func TestShouldReturnUsernameFromLDAPSearchModeMemberOfDN(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "CN=Administrator,CN=Users,DC=example,DC=com", User: "CN=Administrator,CN=Users,DC=example,DC=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -1676,11 +1676,11 @@ func TestShouldReturnErrSearchMemberOf(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "CN=Administrator,CN=Users,DC=example,DC=com", User: "CN=Administrator,CN=Users,DC=example,DC=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -1760,11 +1760,11 @@ func TestShouldReturnErrUnknownSearchMode(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "CN=Administrator,CN=Users,DC=example,DC=com", User: "CN=Administrator,CN=Users,DC=example,DC=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -1836,11 +1836,11 @@ func TestShouldSkipEmptyAttributesSearchModeMemberOf(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "CN=Administrator,CN=Users,DC=example,DC=com", User: "CN=Administrator,CN=Users,DC=example,DC=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -1950,11 +1950,11 @@ func TestShouldSkipEmptyAttributesSearchModeFilter(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "CN=Administrator,CN=Users,DC=example,DC=com", User: "CN=Administrator,CN=Users,DC=example,DC=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -2064,11 +2064,11 @@ func TestShouldSkipEmptyGroupsResultMemberOf(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2146,11 +2146,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndResult(t *testing.T)
mockClientReferralAlt := NewMockLDAPClient(ctrl) mockClientReferralAlt := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2275,11 +2275,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsInErrorAndNoResult(t *testing.
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2366,11 +2366,11 @@ func TestShouldReturnDialErrDuringReferralSearchUsernameFromLDAPWithReferralsInE
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2421,11 +2421,11 @@ func TestShouldReturnSearchErrDuringReferralSearchUsernameFromLDAPWithReferralsI
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2485,11 +2485,11 @@ func TestShouldNotReturnUsernameFromLDAPWithReferralsInErrorAndReferralsNotPermi
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2535,11 +2535,11 @@ func TestShouldReturnUsernameFromLDAPWithReferralsErr(t *testing.T) {
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2626,11 +2626,11 @@ func TestShouldNotUpdateUserPasswordConnect(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2696,11 +2696,11 @@ func TestShouldNotUpdateUserPasswordGetDetails(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2776,11 +2776,11 @@ func TestShouldUpdateUserPassword(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2886,12 +2886,12 @@ func TestShouldUpdateUserPasswordMSAD(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -2999,12 +2999,12 @@ func TestShouldUpdateUserPasswordMSADWithReferrals(t *testing.T) {
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3130,12 +3130,12 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralConnectErr(t *test
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3252,12 +3252,12 @@ func TestShouldUpdateUserPasswordMSADWithReferralsWithReferralModifyErr(t *testi
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3387,12 +3387,12 @@ func TestShouldUpdateUserPasswordMSADWithoutReferrals(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3504,11 +3504,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtension(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3614,11 +3614,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferrals(t *testing.T
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3744,11 +3744,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithoutReferrals(t *testin
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3860,11 +3860,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralConne
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -3981,11 +3981,11 @@ func TestShouldUpdateUserPasswordPasswdModifyExtensionWithReferralsReferralPassw
mockClientReferral := NewMockLDAPClient(ctrl) mockClientReferral := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4115,12 +4115,12 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHints(t *testing
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -4230,12 +4230,12 @@ func TestShouldUpdateUserPasswordActiveDirectoryWithServerPolicyHintsDeprecated(
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -4345,12 +4345,12 @@ func TestShouldUpdateUserPasswordActiveDirectory(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "activedirectory", Implementation: "activedirectory",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
DistinguishedName: "distinguishedName", DistinguishedName: "distinguishedName",
Username: "sAMAccountName", Username: "sAMAccountName",
Mail: "mail", Mail: "mail",
@ -4460,12 +4460,12 @@ func TestShouldUpdateUserPasswordBasic(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Implementation: "custom", Implementation: "custom",
Address: testLDAPAddress, Address: testLDAPAddress,
User: "uid=admin,dc=example,dc=com", User: "uid=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4571,11 +4571,11 @@ func TestShouldReturnErrorWhenMultipleUsernameAttributes(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4640,11 +4640,11 @@ func TestShouldReturnErrorWhenZeroUsernameAttributes(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4709,11 +4709,11 @@ func TestShouldReturnErrorWhenUsernameAttributeNotReturned(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4774,11 +4774,11 @@ func TestShouldReturnErrorWhenMultipleUsersFound(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4860,11 +4860,11 @@ func TestShouldReturnErrorWhenNoDN(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -4929,11 +4929,11 @@ func TestShouldCheckValidUserPassword(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5000,11 +5000,11 @@ func TestShouldNotCheckValidUserPasswordWithConnectError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5042,11 +5042,11 @@ func TestShouldNotCheckValidUserPasswordWithGetProfileError(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5087,11 +5087,11 @@ func TestShouldCheckInvalidUserPassword(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5158,11 +5158,11 @@ func TestShouldCallStartTLSWhenEnabled(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5237,11 +5237,11 @@ func TestShouldParseDynamicConfiguration(t *testing.T) {
mockFactory := NewMockLDAPClientFactory(ctrl) mockFactory := NewMockLDAPClientFactory(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5289,11 +5289,11 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPAddress, Address: testLDAPAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5304,7 +5304,7 @@ func TestShouldCallStartTLSWithInsecureSkipVerifyWhenSkipVerifyTrue(t *testing.T
AdditionalUsersDN: "ou=users", AdditionalUsersDN: "ou=users",
BaseDN: "dc=example,dc=com", BaseDN: "dc=example,dc=com",
StartTLS: true, StartTLS: true,
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
SkipVerify: true, SkipVerify: true,
}, },
}, },
@ -5380,11 +5380,11 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) {
mockClient := NewMockLDAPClient(ctrl) mockClient := NewMockLDAPClient(ctrl)
provider := NewLDAPUserProviderWithFactory( provider := NewLDAPUserProviderWithFactory(
schema.LDAPAuthenticationBackend{ schema.AuthenticationBackendLDAP{
Address: testLDAPSAddress, Address: testLDAPSAddress,
User: "cn=admin,dc=example,dc=com", User: "cn=admin,dc=example,dc=com",
Password: "password", Password: "password",
Attributes: schema.LDAPAuthenticationAttributes{ Attributes: schema.AuthenticationBackendLDAPAttributes{
Username: "uid", Username: "uid",
Mail: "mail", Mail: "mail",
DisplayName: "displayName", DisplayName: "displayName",
@ -5394,7 +5394,7 @@ func TestShouldReturnLDAPSAlreadySecuredWhenStartTLSAttempted(t *testing.T) {
AdditionalUsersDN: "ou=users", AdditionalUsersDN: "ou=users",
BaseDN: "dc=example,dc=com", BaseDN: "dc=example,dc=com",
StartTLS: true, StartTLS: true,
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
SkipVerify: true, SkipVerify: true,
}, },
}, },

View File

@ -8,7 +8,7 @@ import (
) )
// NewAccessControlQuery creates a new AccessControlQuery rule type. // 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 { if len(config) == 0 {
return nil return nil
} }
@ -47,8 +47,8 @@ func (acq AccessControlQuery) IsMatch(object Object) (isMatch bool) {
return true return true
} }
// NewAccessControlQueryObjectMatcher creates a new ObjectMatcher rule type from a schema.ACLQueryRule. // NewAccessControlQueryObjectMatcher creates a new ObjectMatcher rule type from a schema.AccessControlRuleQuery.
func NewAccessControlQueryObjectMatcher(rule schema.ACLQueryRule) (matcher ObjectMatcher, err error) { func NewAccessControlQueryObjectMatcher(rule schema.AccessControlRuleQuery) (matcher ObjectMatcher, err error) {
switch rule.Operator { switch rule.Operator {
case operatorPresent, operatorAbsent: case operatorPresent, operatorAbsent:
return &AccessControlQueryMatcherPresent{key: rule.Key, present: rule.Operator == operatorPresent}, nil return &AccessControlQueryMatcherPresent{key: rule.Key, present: rule.Operator == operatorPresent}, nil

View File

@ -11,13 +11,13 @@ import (
func TestNewAccessControlQuery(t *testing.T) { func TestNewAccessControlQuery(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have [][]schema.ACLQueryRule have [][]schema.AccessControlRuleQuery
expected []AccessControlQuery expected []AccessControlQuery
matches [][]Object matches [][]Object
}{ }{
{ {
"ShouldSkipInvalidTypeEqual", "ShouldSkipInvalidTypeEqual",
[][]schema.ACLQueryRule{ [][]schema.AccessControlRuleQuery{
{ {
{Operator: operatorEqual, Key: "example", Value: 1}, {Operator: operatorEqual, Key: "example", Value: 1},
}, },
@ -27,7 +27,7 @@ func TestNewAccessControlQuery(t *testing.T) {
}, },
{ {
"ShouldSkipInvalidTypePattern", "ShouldSkipInvalidTypePattern",
[][]schema.ACLQueryRule{ [][]schema.AccessControlRuleQuery{
{ {
{Operator: operatorPattern, Key: "example", Value: 1}, {Operator: operatorPattern, Key: "example", Value: 1},
}, },
@ -37,7 +37,7 @@ func TestNewAccessControlQuery(t *testing.T) {
}, },
{ {
"ShouldSkipInvalidOperator", "ShouldSkipInvalidOperator",
[][]schema.ACLQueryRule{ [][]schema.AccessControlRuleQuery{
{ {
{Operator: "nop", Key: "example", Value: 1}, {Operator: "nop", Key: "example", Value: 1},
}, },

View File

@ -7,8 +7,8 @@ import (
"github.com/authelia/authelia/v4/internal/utils" "github.com/authelia/authelia/v4/internal/utils"
) )
// NewAccessControlRules converts a schema.AccessControlConfiguration into an AccessControlRule slice. // NewAccessControlRules converts a schema.AccessControl into an AccessControlRule slice.
func NewAccessControlRules(config schema.AccessControlConfiguration) (rules []*AccessControlRule) { func NewAccessControlRules(config schema.AccessControl) (rules []*AccessControlRule) {
networksMap, networksCacheMap := parseSchemaNetworks(config.Networks) networksMap, networksCacheMap := parseSchemaNetworks(config.Networks)
for i, schemaRule := range config.Rules { 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. // 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{ r := &AccessControlRule{
Position: pos, Position: pos,
Query: NewAccessControlQuery(rule.Query), Query: NewAccessControlQuery(rule.Query),

View File

@ -22,7 +22,7 @@ type AuthorizerTester struct {
*Authorizer *Authorizer
} }
func NewAuthorizerTester(config schema.AccessControlConfiguration) *AuthorizerTester { func NewAuthorizerTester(config schema.AccessControl) *AuthorizerTester {
fullConfig := &schema.Configuration{ fullConfig := &schema.Configuration{
AccessControl: config, AccessControl: config,
} }
@ -51,7 +51,7 @@ func (s *AuthorizerTester) GetRuleMatchResults(subject Subject, requestURI, meth
} }
type AuthorizerTesterBuilder struct { type AuthorizerTesterBuilder struct {
config schema.AccessControlConfiguration config schema.AccessControl
} }
func NewAuthorizerBuilder() *AuthorizerTesterBuilder { func NewAuthorizerBuilder() *AuthorizerTesterBuilder {
@ -63,7 +63,7 @@ func (b *AuthorizerTesterBuilder) WithDefaultPolicy(policy string) *AuthorizerTe
return b 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) b.config.Rules = append(b.config.Rules, rule)
return b return b
} }
@ -133,7 +133,7 @@ func (s *AuthorizerSuite) TestShouldCheckDefaultDeniedConfig() {
func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() { func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"*.example.com"}, Domains: []string{"*.example.com"},
Policy: bypass, Policy: bypass,
}). }).
@ -150,11 +150,11 @@ func (s *AuthorizerSuite) TestShouldCheckMultiDomainRule() {
func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() { func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"{user}.example.com"}, Domains: []string{"{user}.example.com"},
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"{group}.example.com"}, Domains: []string{"{group}.example.com"},
Policy: oneFactor, Policy: oneFactor,
}). }).
@ -169,7 +169,7 @@ func (s *AuthorizerSuite) TestShouldCheckDynamicDomainRules() {
func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() { func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"*.example.com", "other.com"}, Domains: []string{"*.example.com", "other.com"},
Policy: bypass, Policy: bypass,
}). }).
@ -189,15 +189,15 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleDomainRule() {
func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() { func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"single.example.com"}, Domains: []string{"single.example.com"},
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: bypass, Policy: bypass,
}). }).
@ -212,9 +212,9 @@ func (s *AuthorizerSuite) TestShouldCheckFactorsPolicy() {
func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() { func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"one.example.com"}, Domains: []string{"one.example.com"},
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{ {
Operator: operatorEqual, Operator: operatorEqual,
@ -235,9 +235,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
}, },
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"two.example.com"}, Domains: []string{"two.example.com"},
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{ {
Operator: operatorEqual, Operator: operatorEqual,
@ -255,9 +255,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
}, },
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"three.example.com"}, Domains: []string{"three.example.com"},
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{ {
Operator: operatorNotEqual, Operator: operatorNotEqual,
@ -273,9 +273,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
}, },
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"four.example.com"}, Domains: []string{"four.example.com"},
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{ {
Operator: operatorPattern, Operator: operatorPattern,
@ -286,9 +286,9 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
}, },
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"five.example.com"}, Domains: []string{"five.example.com"},
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{ {
Operator: operatorNotPattern, Operator: operatorNotPattern,
@ -335,16 +335,16 @@ func (s *AuthorizerSuite) TestShouldCheckQueryPolicy() {
func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() { func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: bypass, Policy: bypass,
Subjects: [][]string{{"user:john"}}, Subjects: [][]string{{"user:john"}},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"*.example.com"}, Domains: []string{"*.example.com"},
Policy: twoFactor, Policy: twoFactor,
}). }).
@ -357,24 +357,24 @@ func (s *AuthorizerSuite) TestShouldCheckRulePrecedence() {
func (s *AuthorizerSuite) TestShouldCheckDomainMatching() { func (s *AuthorizerSuite) TestShouldCheckDomainMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: bypass, Policy: bypass,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"one-factor.example.com"}, Domains: []string{"one-factor.example.com"},
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"two-factor.example.com"}, Domains: []string{"two-factor.example.com"},
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"*.example.com"}, Domains: []string{"*.example.com"},
Policy: oneFactor, Policy: oneFactor,
Subjects: [][]string{{"group:admins"}}, Subjects: [][]string{{"group:admins"}},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"*.example.com"}, Domains: []string{"*.example.com"},
Policy: twoFactor, Policy: twoFactor,
}). }).
@ -466,23 +466,23 @@ func (s *AuthorizerSuite) TestShouldCheckDomainRegexMatching() {
} }
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example.com$`}), DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example.com$`}),
Policy: bypass, Policy: bypass,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example2.com$`}), DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.example2.com$`}),
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^(?P<User>[a-zA-Z0-9]+)\.regex.com$`}), DomainsRegex: createSliceRegexRule(s.T(), []string{`^(?P<User>[a-zA-Z0-9]+)\.regex.com$`}),
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^group-(?P<Group>[a-zA-Z0-9]+)\.regex.com$`}), DomainsRegex: createSliceRegexRule(s.T(), []string{`^group-(?P<Group>[a-zA-Z0-9]+)\.regex.com$`}),
Policy: twoFactor, Policy: twoFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.(one|two).com$`}), DomainsRegex: createSliceRegexRule(s.T(), []string{`^.*\.(one|two).com$`}),
Policy: twoFactor, Policy: twoFactor,
}). }).
@ -548,17 +548,17 @@ func (s *AuthorizerSuite) TestShouldCheckResourceSubjectMatching() {
} }
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"id.example.com"}, Domains: []string{"id.example.com"},
Policy: oneFactor, Policy: oneFactor,
Resources: createSliceRegexRule(s.T(), []string{`^/(?P<User>[a-zA-Z0-9]+)/personal(/|/.*)?$`, `^/(?P<Group>[a-zA-Z0-9]+)/group(/|/.*)?$`}), 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"}, Domains: []string{"id.example.com"},
Policy: deny, Policy: deny,
Resources: createSliceRegexRule(s.T(), []string{`^/([a-zA-Z0-9]+)/personal(/|/.*)?$`, `^/([a-zA-Z0-9]+)/group(/|/.*)?$`}), 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"}, Domains: []string{"id.example.com"},
Policy: bypass, Policy: bypass,
}). }).
@ -629,7 +629,7 @@ func (s *AuthorizerSuite) TestShouldCheckResourceSubjectMatching() {
func (s *AuthorizerSuite) TestShouldCheckUserMatching() { func (s *AuthorizerSuite) TestShouldCheckUserMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Subjects: [][]string{{"user:john"}}, Subjects: [][]string{{"user:john"}},
@ -643,7 +643,7 @@ func (s *AuthorizerSuite) TestShouldCheckUserMatching() {
func (s *AuthorizerSuite) TestShouldCheckGroupMatching() { func (s *AuthorizerSuite) TestShouldCheckGroupMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Subjects: [][]string{{"group:admins"}}, Subjects: [][]string{{"group:admins"}},
@ -657,7 +657,7 @@ func (s *AuthorizerSuite) TestShouldCheckGroupMatching() {
func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Subjects: [][]string{{"group:admins"}, {"user:bob"}}, Subjects: [][]string{{"group:admins"}, {"user:bob"}},
@ -673,7 +673,7 @@ func (s *AuthorizerSuite) TestShouldCheckSubjectsMatching() {
func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() { func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Subjects: [][]string{{"group:admins", "user:bob"}, {"group:admins", "group:dev"}}, Subjects: [][]string{{"group:admins", "user:bob"}, {"group:admins", "group:dev"}},
@ -688,27 +688,27 @@ func (s *AuthorizerSuite) TestShouldCheckMultipleSubjectsMatching() {
func (s *AuthorizerSuite) TestShouldCheckIPMatching() { func (s *AuthorizerSuite) TestShouldCheckIPMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: bypass, Policy: bypass,
Networks: []string{"192.168.1.8", "10.0.0.8"}, Networks: []string{"192.168.1.8", "10.0.0.8"},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Networks: []string{"10.0.0.7"}, Networks: []string{"10.0.0.7"},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"net.example.com"}, Domains: []string{"net.example.com"},
Policy: twoFactor, Policy: twoFactor,
Networks: []string{"10.0.0.0/8"}, Networks: []string{"10.0.0.0/8"},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"ipv6.example.com"}, Domains: []string{"ipv6.example.com"},
Policy: twoFactor, Policy: twoFactor,
Networks: []string{"fec0::1/64"}, Networks: []string{"fec0::1/64"},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"ipv6-alt.example.com"}, Domains: []string{"ipv6-alt.example.com"},
Policy: twoFactor, Policy: twoFactor,
Networks: []string{"fec0::1"}, Networks: []string{"fec0::1"},
@ -732,17 +732,17 @@ func (s *AuthorizerSuite) TestShouldCheckIPMatching() {
func (s *AuthorizerSuite) TestShouldCheckMethodMatching() { func (s *AuthorizerSuite) TestShouldCheckMethodMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: bypass, Policy: bypass,
Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace}, Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: oneFactor, Policy: oneFactor,
Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch, fasthttp.MethodPost}, Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch, fasthttp.MethodPost},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"protected.example.com"}, Domains: []string{"protected.example.com"},
Policy: twoFactor, Policy: twoFactor,
Methods: []string{fasthttp.MethodDelete}, Methods: []string{fasthttp.MethodDelete},
@ -773,27 +773,27 @@ func (s *AuthorizerSuite) TestShouldCheckResourceMatching() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"resource.example.com"}, Domains: []string{"resource.example.com"},
Policy: bypass, Policy: bypass,
Resources: createSliceRegexRule(s.T(), []string{"^/case/[a-z]+$", "^/$"}), Resources: createSliceRegexRule(s.T(), []string{"^/case/[a-z]+$", "^/$"}),
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"resource.example.com"}, Domains: []string{"resource.example.com"},
Policy: bypass, Policy: bypass,
Resources: createSliceRegexRule(s.T(), []string{"^/bypass/.*$", "^/$", "embedded"}), Resources: createSliceRegexRule(s.T(), []string{"^/bypass/.*$", "^/$", "embedded"}),
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"resource.example.com"}, Domains: []string{"resource.example.com"},
Policy: oneFactor, Policy: oneFactor,
Resources: createSliceRegexRule(s.T(), []string{"^/one_factor/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/one_factor/.*$"}),
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"resource.example.com"}, Domains: []string{"resource.example.com"},
Policy: twoFactor, Policy: twoFactor,
Resources: createSliceRegexRule(s.T(), []string{"^/a/longer/rule/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/a/longer/rule/.*$"}),
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"resource.example.com"}, Domains: []string{"resource.example.com"},
Policy: twoFactor, Policy: twoFactor,
Resources: createSliceRegexRule(s.T(), []string{"^/an/exact/path/$"}), 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. // This test assures that rules without domains (not allowed by schema validator at this time) will pass validation correctly.
func (s *AuthorizerSuite) TestShouldMatchAnyDomainIfBlank() { func (s *AuthorizerSuite) TestShouldMatchAnyDomainIfBlank() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Policy: bypass, Policy: bypass,
Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace}, Methods: []string{fasthttp.MethodOptions, fasthttp.MethodHead, fasthttp.MethodGet, fasthttp.MethodConnect, fasthttp.MethodTrace},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Policy: oneFactor, Policy: oneFactor,
Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch}, Methods: []string{fasthttp.MethodPut, fasthttp.MethodPatch},
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Policy: twoFactor, Policy: twoFactor,
Methods: []string{fasthttp.MethodDelete}, Methods: []string{fasthttp.MethodDelete},
}). }).
@ -875,37 +875,37 @@ func (s *AuthorizerSuite) TestShouldMatchResourceWithSubjectRules() {
tester := NewAuthorizerBuilder(). tester := NewAuthorizerBuilder().
WithDefaultPolicy(deny). WithDefaultPolicy(deny).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}),
Subjects: [][]string{{"group:admins"}}, Subjects: [][]string{{"group:admins"}},
Policy: oneFactor, Policy: oneFactor,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}),
Policy: deny, Policy: deny,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: bypass, Policy: bypass,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public2.example.com"}, Domains: []string{"public2.example.com"},
Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}),
Subjects: [][]string{{"group:admins"}}, Subjects: [][]string{{"group:admins"}},
Policy: bypass, Policy: bypass,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public2.example.com"}, Domains: []string{"public2.example.com"},
Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}), Resources: createSliceRegexRule(s.T(), []string{"^/admin/.*$"}),
Policy: deny, Policy: deny,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"public2.example.com"}, Domains: []string{"public2.example.com"},
Policy: bypass, Policy: bypass,
}). }).
WithRule(schema.ACLRule{ WithRule(schema.AccessControlRule{
Domains: []string{"private.example.com"}, Domains: []string{"private.example.com"},
Subjects: [][]string{{"group:admins"}}, Subjects: [][]string{{"group:admins"}},
Policy: twoFactor, Policy: twoFactor,
@ -1004,9 +1004,9 @@ func TestRunSuite(t *testing.T) {
func TestNewAuthorizer(t *testing.T) { func TestNewAuthorizer(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
AccessControl: schema.AccessControlConfiguration{ AccessControl: schema.AccessControl{
DefaultPolicy: deny, DefaultPolicy: deny,
Rules: []schema.ACLRule{ Rules: []schema.AccessControlRule{
{ {
Domains: []string{"example.com"}, Domains: []string{"example.com"},
Policy: twoFactor, Policy: twoFactor,
@ -1039,9 +1039,9 @@ func TestNewAuthorizer(t *testing.T) {
func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) { func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
AccessControl: schema.AccessControlConfiguration{ AccessControl: schema.AccessControl{
DefaultPolicy: deny, DefaultPolicy: deny,
Rules: []schema.ACLRule{ Rules: []schema.AccessControlRule{
{ {
Domains: []string{"example.com"}, Domains: []string{"example.com"},
Policy: oneFactor, Policy: oneFactor,
@ -1060,9 +1060,9 @@ func TestAuthorizerIsSecondFactorEnabledRuleWithNoOIDC(t *testing.T) {
func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) { func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
AccessControl: schema.AccessControlConfiguration{ AccessControl: schema.AccessControl{
DefaultPolicy: deny, DefaultPolicy: deny,
Rules: []schema.ACLRule{ Rules: []schema.AccessControlRule{
{ {
Domains: []string{"example.com"}, Domains: []string{"example.com"},
Policy: oneFactor, Policy: oneFactor,
@ -1070,8 +1070,8 @@ func TestAuthorizerIsSecondFactorEnabledRuleWithOIDC(t *testing.T) {
}, },
}, },
IdentityProviders: schema.IdentityProviders{ IdentityProviders: schema.IdentityProviders{
OIDC: &schema.OpenIDConnect{ OIDC: &schema.IdentityProvidersOpenIDConnect{
Clients: []schema.OpenIDConnectClient{ Clients: []schema.IdentityProvidersOpenIDConnectClient{
{ {
Policy: oneFactor, Policy: oneFactor,
}, },

View File

@ -138,7 +138,7 @@ func schemaNetworksToACL(networkRules []string, networksMap map[string][]*net.IP
return networks 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. // 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. // The networksMap contains the named networks as keys, the networksCacheMap contains the CIDR notations as keys.
networksMap = map[string][]*net.IPNet{} networksMap = map[string][]*net.IPNet{}

View File

@ -60,7 +60,7 @@ func TestShouldSplitDomainCorrectly(t *testing.T) {
} }
func TestShouldParseRuleNetworks(t *testing.T) { func TestShouldParseRuleNetworks(t *testing.T) {
schemaNetworks := []schema.ACLNetwork{ schemaNetworks := []schema.AccessControlNetwork{
{ {
Name: "desktop", Name: "desktop",
Networks: []string{ Networks: []string{
@ -105,7 +105,7 @@ func TestShouldParseRuleNetworks(t *testing.T) {
} }
func TestShouldParseACLNetworks(t *testing.T) { func TestShouldParseACLNetworks(t *testing.T) {
schemaNetworks := []schema.ACLNetwork{ schemaNetworks := []schema.AccessControlNetwork{
{ {
Name: "test", Name: "test",
Networks: []string{ Networks: []string{

View File

@ -16,7 +16,6 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"github.com/authelia/authelia/v4/internal/authentication" "github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/server" "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. // NewFileWatcherService creates a new FileWatcherService with the appropriate logger etc.
func NewFileWatcherService(name, path string, reload ProviderReload, log *logrus.Logger) (service *FileWatcherService, err error) { func NewFileWatcherService(name, path string, reload ProviderReload, log *logrus.Logger) (service *FileWatcherService, err error) {
if path == "" { if path == "" {
@ -173,54 +161,6 @@ func (service *ServerService) Log() *logrus.Entry {
return service.log 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. // FileWatcherService is a Service that watches files for changes.
type FileWatcherService struct { type FileWatcherService struct {
name string name string
@ -332,19 +272,6 @@ func svcSvrMetricsFunc(ctx *CmdCtx) (service Service) {
return 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) { func svcWatcherUsersFunc(ctx *CmdCtx) (service Service) {
var err error var err error
@ -385,7 +312,7 @@ func servicesRun(ctx *CmdCtx) {
) )
for _, serviceFunc := range []func(ctx *CmdCtx) Service{ for _, serviceFunc := range []func(ctx *CmdCtx) Service{
svcSvrMainFunc, svcSvrGRPCFunc, svcSvrMetricsFunc, svcSvrMainFunc, svcSvrMetricsFunc,
svcWatcherUsersFunc, svcWatcherUsersFunc,
} { } {
if service := serviceFunc(ctx); service != nil { if service := serviceFunc(ctx); service != nil {

View File

@ -490,7 +490,7 @@ func StringToCryptoPrivateKeyHookFunc() mapstructure.DecodeHookFuncType {
return data, nil return data, nil
} }
field, _ := reflect.TypeOf(schema.TLSConfig{}).FieldByName("PrivateKey") field, _ := reflect.TypeOf(schema.TLS{}).FieldByName("PrivateKey")
expectedType := field.Type expectedType := field.Type
if t != expectedType { if t != expectedType {

View File

@ -1,43 +1,44 @@
package schema package schema
import ( // AccessControl represents the configuration related to ACLs.
"regexp" 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. // Represents a list of named network groups.
type AccessControlConfiguration struct { 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"`
DefaultPolicy string `koanf:"default_policy"`
Networks []ACLNetwork `koanf:"networks"` // The ACL rules list.
Rules []ACLRule `koanf:"rules"` 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. // AccessControlNetwork represents one ACL network group entry.
type ACLNetwork struct { type AccessControlNetwork struct {
Name string `koanf:"name"` 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 []string `koanf:"networks"` 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. // AccessControlRule represents one ACL rule entry.
type ACLRule struct { type AccessControlRule struct {
Domains []string `koanf:"domain"` 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 []regexp.Regexp `koanf:"domain_regex"` 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"` 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 [][]string `koanf:"subject"` Subjects AccessControlRuleSubjects `koanf:"subject" json:"subject" jsonschema:"title=AccessControlRuleSubjects" jsonschema_description:"The users or groups that this rule applies to"`
Networks []string `koanf:"networks"` 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 []regexp.Regexp `koanf:"resources"` 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 []string `koanf:"methods"` 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 [][]ACLQueryRule `koanf:"query"` 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. // AccessControlRuleQuery represents the ACL query criteria.
type ACLQueryRule struct { type AccessControlRuleQuery struct {
Operator string `koanf:"operator"` 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"` Key string `koanf:"key" json:"key" jsonschema:"required,title=Key" jsonschema_description:"The Query Parameter key this rule applies to"`
Value any `koanf:"value"` 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. // DefaultACLNetwork represents the default configuration related to access control network group configuration.
var DefaultACLNetwork = []ACLNetwork{ var DefaultACLNetwork = []AccessControlNetwork{
{ {
Name: "localhost", Name: "localhost",
Networks: []string{"127.0.0.1"}, Networks: []string{"127.0.0.1"},
@ -49,7 +50,7 @@ var DefaultACLNetwork = []ACLNetwork{
} }
// DefaultACLRule represents the default configuration related to access control rule configuration. // DefaultACLRule represents the default configuration related to access control rule configuration.
var DefaultACLRule = []ACLRule{ var DefaultACLRule = []AccessControlRule{
{ {
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: "bypass", Policy: "bypass",

View File

@ -8,132 +8,143 @@ import (
// AuthenticationBackend represents the configuration related to the authentication backend. // AuthenticationBackend represents the configuration related to the authentication backend.
type AuthenticationBackend struct { 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"` // The file authentication backend configuration.
LDAP *LDAPAuthenticationBackend `koanf:"ldap"` 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. // AuthenticationBackendPasswordReset represents the configuration related to password reset functionality.
type PasswordResetAuthenticationBackend struct { type AuthenticationBackendPasswordReset struct {
Disable bool `koanf:"disable"` Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the Password Reset option"`
CustomURL url.URL `koanf:"custom_url"` 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. // AuthenticationBackendFile represents the configuration related to file-based backend.
type FileAuthenticationBackend struct { type AuthenticationBackendFile struct {
Path string `koanf:"path"` Path string `koanf:"path" json:"path" jsonschema:"title=Path" jsonschema_description:"The file path to the user database"`
Watch bool `koanf:"watch"` 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"`
Password Password `koanf:"password"`
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. // AuthenticationBackendFileSearch represents the configuration related to file-based backend searching.
type FileSearchAuthenticationBackend struct { type AuthenticationBackendFileSearch struct {
Email bool `koanf:"email"` 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"` 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. // AuthenticationBackendFilePassword represents the configuration related to password hashing.
type Password struct { type AuthenticationBackendFilePassword struct {
Algorithm string `koanf:"algorithm"` 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"` Argon2 AuthenticationBackendFilePasswordArgon2 `koanf:"argon2" json:"argon2" jsonschema:"title=Argon2" jsonschema_description:"Configure the Argon2 password hashing parameters"`
SHA2Crypt SHA2CryptPassword `koanf:"sha2crypt"` SHA2Crypt AuthenticationBackendFilePasswordSHA2Crypt `koanf:"sha2crypt" json:"sha2crypt" jsonschema:"title=SHA2Crypt" jsonschema_description:"Configure the SHA2Crypt password hashing parameters"`
PBKDF2 PBKDF2Password `koanf:"pbkdf2"` PBKDF2 AuthenticationBackendFilePasswordPBKDF2 `koanf:"pbkdf2" json:"pbkdf2" jsonschema:"title=PBKDF2" jsonschema_description:"Configure the PBKDF2 password hashing parameters"`
BCrypt BCryptPassword `koanf:"bcrypt"` BCrypt AuthenticationBackendFilePasswordBCrypt `koanf:"bcrypt" json:"bcrypt" jsonschema:"title=BCrypt" jsonschema_description:"Configure the BCrypt password hashing parameters"`
SCrypt SCryptPassword `koanf:"scrypt"` SCrypt AuthenticationBackendFilePasswordSCrypt `koanf:"scrypt" json:"scrypt" jsonschema:"title=SCrypt" jsonschema_description:"Configure the SCrypt password hashing parameters"`
Iterations int `koanf:"iterations"` // Deprecated: Use individual password options instead.
Memory int `koanf:"memory"` Iterations int `koanf:"iterations" json:"iterations" jsonschema:"deprecated"`
Parallelism int `koanf:"parallelism"`
KeyLength int `koanf:"key_length"` // Deprecated: Use individual password options instead.
SaltLength int `koanf:"salt_length"` 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. // AuthenticationBackendFilePasswordArgon2 represents the argon2 hashing settings.
type Argon2Password struct { type AuthenticationBackendFilePasswordArgon2 struct {
Variant string `koanf:"variant"` 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"` 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"` 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"` 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"` 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"` 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. // AuthenticationBackendFilePasswordSHA2Crypt represents the sha2crypt hashing settings.
type SHA2CryptPassword struct { type AuthenticationBackendFilePasswordSHA2Crypt struct {
Variant string `koanf:"variant"` 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"` 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"` 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. // AuthenticationBackendFilePasswordPBKDF2 represents the PBKDF2 hashing settings.
type PBKDF2Password struct { type AuthenticationBackendFilePasswordPBKDF2 struct {
Variant string `koanf:"variant"` 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"` 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"` 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. // AuthenticationBackendFilePasswordBCrypt represents the bcrypt hashing settings.
type BCryptPassword struct { type AuthenticationBackendFilePasswordBCrypt struct {
Variant string `koanf:"variant"` 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"` 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. // AuthenticationBackendFilePasswordSCrypt represents the scrypt hashing settings.
type SCryptPassword struct { type AuthenticationBackendFilePasswordSCrypt struct {
Iterations int `koanf:"iterations"` 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"` 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"` 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"` 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"` 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. // AuthenticationBackendLDAP represents the configuration related to LDAP server.
type LDAPAuthenticationBackend struct { type AuthenticationBackendLDAP struct {
Address *AddressLDAP `koanf:"address"` Address *AddressLDAP `koanf:"address" json:"address" jsonschema:"title=Address" jsonschema_description:"The address of the LDAP directory server"`
Implementation string `koanf:"implementation"` 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"` 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"` StartTLS bool `koanf:"start_tls" json:"start_tls" jsonschema:"default=false,title=StartTLS" jsonschema_description:"Enables the use of StartTLS"`
TLS *TLSConfig `koanf:"tls"` 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"` 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"` 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"` 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"` 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"` GroupSearchMode string `koanf:"group_search_mode"`
Attributes LDAPAuthenticationAttributes `koanf:"attributes"` Attributes AuthenticationBackendLDAPAttributes `koanf:"attributes" json:"attributes"`
PermitReferrals bool `koanf:"permit_referrals"` 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"` 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"` 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"` User string `koanf:"user" json:"user" jsonschema:"title=User" jsonschema_description:"The user distinguished name for LDAP binding"`
Password string `koanf:"password"` 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. // AuthenticationBackendLDAPAttributes represents the configuration related to LDAP server attributes.
type LDAPAuthenticationAttributes struct { type AuthenticationBackendLDAPAttributes struct {
DistinguishedName string `koanf:"distinguished_name"` 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"` 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"` 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"` 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"` 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"` 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. // DefaultPasswordConfig represents the default configuration related to Argon2id hashing.
var DefaultPasswordConfig = Password{ var DefaultPasswordConfig = AuthenticationBackendFilePassword{
Algorithm: argon2, Algorithm: argon2,
Argon2: Argon2Password{ Argon2: AuthenticationBackendFilePasswordArgon2{
Variant: argon2id, Variant: argon2id,
Iterations: 3, Iterations: 3,
Memory: 64 * 1024, Memory: 64 * 1024,
@ -141,21 +152,21 @@ var DefaultPasswordConfig = Password{
KeyLength: 32, KeyLength: 32,
SaltLength: 16, SaltLength: 16,
}, },
SHA2Crypt: SHA2CryptPassword{ SHA2Crypt: AuthenticationBackendFilePasswordSHA2Crypt{
Variant: sha512, Variant: sha512,
Iterations: 50000, Iterations: 50000,
SaltLength: 16, SaltLength: 16,
}, },
PBKDF2: PBKDF2Password{ PBKDF2: AuthenticationBackendFilePasswordPBKDF2{
Variant: sha512, Variant: sha512,
Iterations: 310000, Iterations: 310000,
SaltLength: 16, SaltLength: 16,
}, },
BCrypt: BCryptPassword{ BCrypt: AuthenticationBackendFilePasswordBCrypt{
Variant: "standard", Variant: "standard",
Cost: 12, Cost: 12,
}, },
SCrypt: SCryptPassword{ SCrypt: AuthenticationBackendFilePasswordSCrypt{
Iterations: 16, Iterations: 16,
BlockSize: 8, BlockSize: 8,
Parallelism: 1, Parallelism: 1,
@ -165,16 +176,16 @@ var DefaultPasswordConfig = Password{
} }
// DefaultCIPasswordConfig represents the default configuration related to Argon2id hashing for CI. // DefaultCIPasswordConfig represents the default configuration related to Argon2id hashing for CI.
var DefaultCIPasswordConfig = Password{ var DefaultCIPasswordConfig = AuthenticationBackendFilePassword{
Algorithm: argon2, Algorithm: argon2,
Argon2: Argon2Password{ Argon2: AuthenticationBackendFilePasswordArgon2{
Iterations: 3, Iterations: 3,
Memory: 64, Memory: 64,
Parallelism: 4, Parallelism: 4,
KeyLength: 32, KeyLength: 32,
SaltLength: 16, SaltLength: 16,
}, },
SHA2Crypt: SHA2CryptPassword{ SHA2Crypt: AuthenticationBackendFilePasswordSHA2Crypt{
Variant: sha512, Variant: sha512,
Iterations: 50000, Iterations: 50000,
SaltLength: 16, SaltLength: 16,
@ -182,26 +193,26 @@ var DefaultCIPasswordConfig = Password{
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationCustom represents the default LDAP config. // DefaultLDAPAuthenticationBackendConfigurationImplementationCustom represents the default LDAP config.
var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = LDAPAuthenticationBackend{ var DefaultLDAPAuthenticationBackendConfigurationImplementationCustom = AuthenticationBackendLDAP{
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
Username: ldapAttrUserID, Username: ldapAttrUserID,
DisplayName: ldapAttrDisplayName, DisplayName: ldapAttrDisplayName,
Mail: ldapAttrMail, Mail: ldapAttrMail,
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory represents the default LDAP config for the LDAPImplementationActiveDirectory Implementation. // 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})))", 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)))", GroupsFilter: "(&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912)))",
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
DistinguishedName: ldapAttrDistinguishedName, DistinguishedName: ldapAttrDistinguishedName,
Username: ldapAttrSAMAccountName, Username: ldapAttrSAMAccountName,
DisplayName: ldapAttrDisplayName, DisplayName: ldapAttrDisplayName,
@ -210,17 +221,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory =
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis represents the default LDAP config for the LDAPImplementationRFC2307bis Implementation. // 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)))", UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(|(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))",
GroupsFilter: "(&(|(member={dn})(uniqueMember={dn}))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=groupOfMembers))(!(pwdReset=TRUE)))", GroupsFilter: "(&(|(member={dn})(uniqueMember={dn}))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=groupOfMembers))(!(pwdReset=TRUE)))",
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
Username: ldapAttrUserID, Username: ldapAttrUserID,
DisplayName: ldapAttrDisplayName, DisplayName: ldapAttrDisplayName,
Mail: ldapAttrMail, Mail: ldapAttrMail,
@ -228,17 +239,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis = LDAP
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA represents the default LDAP config for the LDAPImplementationFreeIPA Implementation. // 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})))", 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))", GroupsFilter: "(&(member={dn})(objectClass=groupOfNames))",
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
Username: ldapAttrUserID, Username: ldapAttrUserID,
DisplayName: ldapAttrDisplayName, DisplayName: ldapAttrDisplayName,
Mail: ldapAttrMail, Mail: ldapAttrMail,
@ -246,19 +257,19 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAut
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP represents the default LDAP config for the LDAPImplementationLLDAP Implementation. // DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP represents the default LDAP config for the LDAPImplementationLLDAP Implementation.
var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = LDAPAuthenticationBackend{ var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = AuthenticationBackendLDAP{
AdditionalUsersDN: "OU=people", AdditionalUsersDN: "OU=people",
AdditionalGroupsDN: "OU=groups", AdditionalGroupsDN: "OU=groups",
UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))", UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))",
GroupsFilter: "(&(member={dn})(objectClass=groupOfUniqueNames))", GroupsFilter: "(&(member={dn})(objectClass=groupOfUniqueNames))",
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
Username: ldapAttrUserID, Username: ldapAttrUserID,
DisplayName: ldapAttrCommonName, DisplayName: ldapAttrCommonName,
Mail: ldapAttrMail, Mail: ldapAttrMail,
@ -266,17 +277,17 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP = LDAPAuthe
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth represents the default LDAP config for the LDAPImplementationGLAuth Implementation. // 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)))", UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=posixAccount)(!(accountStatus=inactive)))",
GroupsFilter: "(&(uniqueMember={dn})(objectClass=posixGroup))", GroupsFilter: "(&(uniqueMember={dn})(objectClass=posixGroup))",
GroupSearchMode: ldapGroupSearchModeFilter, GroupSearchMode: ldapGroupSearchModeFilter,
Attributes: LDAPAuthenticationAttributes{ Attributes: AuthenticationBackendLDAPAttributes{
Username: ldapAttrCommonName, Username: ldapAttrCommonName,
DisplayName: ldapAttrDescription, DisplayName: ldapAttrDescription,
Mail: ldapAttrMail, Mail: ldapAttrMail,
@ -284,7 +295,7 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth = LDAPAuth
GroupName: ldapAttrCommonName, GroupName: ldapAttrCommonName,
}, },
Timeout: time.Second * 5, Timeout: time.Second * 5,
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }

View File

@ -2,26 +2,26 @@ package schema
// Configuration object extracted from YAML configuration file. // Configuration object extracted from YAML configuration file.
type Configuration struct { type Configuration struct {
Theme string `koanf:"theme"` 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"` 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"` 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"` 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"` 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"` Log Log `koanf:"log" json:"log" jsonschema:"title=Log" jsonschema_description:"Logging Configuration"`
IdentityProviders IdentityProviders `koanf:"identity_providers"` IdentityProviders IdentityProviders `koanf:"identity_providers" json:"identity_providers" jsonschema:"title=Identity Providers" jsonschema_description:"Identity Providers Configuration"`
AuthenticationBackend AuthenticationBackend `koanf:"authentication_backend"` AuthenticationBackend AuthenticationBackend `koanf:"authentication_backend" json:"authentication_backend" jsonschema:"title=Authentication Backend" jsonschema_description:"Authentication Backend Configuration"`
Session SessionConfiguration `koanf:"session"` Session Session `koanf:"session" json:"session" jsonschema:"title=Session" jsonschema_description:"Session Configuration"`
TOTP TOTPConfiguration `koanf:"totp"` TOTP TOTP `koanf:"totp" json:"totp" jsonschema:"title=TOTP" jsonschema_description:"Time-based One Time Password Configuration"`
DuoAPI DuoAPIConfiguration `koanf:"duo_api"` DuoAPI DuoAPI `koanf:"duo_api" json:"duo_api" jsonschema:"title=Duo API" jsonschema_description:"Duo API Configuration"`
AccessControl AccessControlConfiguration `koanf:"access_control"` AccessControl AccessControl `koanf:"access_control" json:"access_control" jsonschema:"title=Access Control" jsonschema_description:"Access Control Configuration"`
NTP NTPConfiguration `koanf:"ntp"` NTP NTP `koanf:"ntp" json:"ntp" jsonschema:"title=NTP" jsonschema_description:"Network Time Protocol Configuration"`
Regulation RegulationConfiguration `koanf:"regulation"` Regulation Regulation `koanf:"regulation" json:"regulation" jsonschema:"title=Regulation" jsonschema_description:"Regulation Configuration"`
Storage StorageConfiguration `koanf:"storage"` Storage Storage `koanf:"storage" json:"storage" jsonschema:"title=Storage" jsonschema_description:"Storage Configuration"`
Notifier NotifierConfiguration `koanf:"notifier"` Notifier Notifier `koanf:"notifier" json:"notifier" jsonschema:"title=Notifier" jsonschema_description:"Notifier Configuration"`
Server ServerConfiguration `koanf:"server"` Server Server `koanf:"server" json:"server" jsonschema:"title=Server" jsonschema_description:"Server Configuration"`
Telemetry TelemetryConfig `koanf:"telemetry"` Telemetry Telemetry `koanf:"telemetry" json:"telemetry" jsonschema:"title=Telemetry" jsonschema_description:"Telemetry Configuration"`
WebAuthn WebAuthnConfiguration `koanf:"webauthn"` WebAuthn WebAuthn `koanf:"webauthn" json:"webauthn" jsonschema:"title=WebAuthn" jsonschema_description:"WebAuthn Configuration"`
PasswordPolicy PasswordPolicyConfiguration `koanf:"password_policy"` PasswordPolicy PasswordPolicy `koanf:"password_policy" json:"password_policy" jsonschema:"title=Password Policy" jsonschema_description:"Password Policy Configuration"`
PrivacyPolicy PrivacyPolicy `koanf:"privacy_policy"` 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 package schema
// DuoAPIConfiguration represents the configuration related to Duo API. // DuoAPI represents the configuration related to Duo API.
type DuoAPIConfiguration struct { type DuoAPI struct {
Disable bool `koanf:"disable"` Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disable the Duo API integration"`
Hostname string `koanf:"hostname"` 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"` 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"` 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"` 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. // IdentityProviders represents the Identity Providers configuration for Authelia.
type IdentityProviders struct { type IdentityProviders struct {
OIDC *OpenIDConnect `koanf:"oidc"` OIDC *IdentityProvidersOpenIDConnect `koanf:"oidc" json:"oidc"`
} }
// OpenIDConnect configuration for OpenID Connect 1.0. // IdentityProvidersOpenIDConnect represents the configuration for OpenID Connect 1.0.
type OpenIDConnect struct { type IdentityProvidersOpenIDConnect struct {
HMACSecret string `koanf:"hmac_secret"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` PAR IdentityProvidersOpenIDConnectPAR `koanf:"pushed_authorizations" json:"pushed_authorizations" jsonschema:"title=Pushed Authorizations" jsonschema_description:"Configuration options for Pushed Authorization Requests"`
CORS OpenIDConnectCORS `koanf:"cors"` 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. // OpenIDConnectDiscovery is information discovered during validation reused for the discovery handlers.
@ -47,68 +47,68 @@ type OpenIDConnectDiscovery struct {
RequestObjectSigningAlgs []string RequestObjectSigningAlgs []string
} }
// OpenIDConnectPAR represents an OpenID Connect 1.0 PAR config. // IdentityProvidersOpenIDConnectPAR represents an OpenID Connect 1.0 PAR config.
type OpenIDConnectPAR struct { type IdentityProvidersOpenIDConnectPAR struct {
Enforce bool `koanf:"enforce"` 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"` 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. // IdentityProvidersOpenIDConnectCORS represents an OpenID Connect 1.0 CORS config.
type OpenIDConnectCORS struct { type IdentityProvidersOpenIDConnectCORS struct {
Endpoints []string `koanf:"endpoints"` 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"` 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. // IdentityProvidersOpenIDConnectClient represents a configuration for an OpenID Connect 1.0 client.
type OpenIDConnectClient struct { type IdentityProvidersOpenIDConnectClient struct {
ID string `koanf:"id"` ID string `koanf:"id" json:"id" jsonschema:"required,minLength=1,title=ID" jsonschema_description:"The Client ID"`
Description string `koanf:"description"` Description string `koanf:"description" json:"description" jsonschema:"title=Description" jsonschema_description:"The Client Description for End-Users"`
Secret *PasswordDigest `koanf:"secret"` Secret *PasswordDigest `koanf:"secret" json:"secret" jsonschema:"title=Secret" jsonschema_description:"The Client Secret for Client Authentication"`
SectorIdentifier url.URL `koanf:"sector_identifier"` 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"` 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"` Audience []string `koanf:"audience" json:"audience" jsonschema:"uniqueItems,title=Audience" jsonschema_description:"List of authorized audiences"`
Scopes []string `koanf:"scopes"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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"` 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. // IdentityProvidersOpenIDConnectClientPublicKeys represents the Client Public Keys configuration for an OpenID Connect 1.0 client.
type OpenIDConnectClientPublicKeys struct { type IdentityProvidersOpenIDConnectClientPublicKeys struct {
URI *url.URL `koanf:"uri"` 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"` 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. // DefaultOpenIDConnectConfiguration contains defaults for OIDC.
var DefaultOpenIDConnectConfiguration = OpenIDConnect{ var DefaultOpenIDConnectConfiguration = IdentityProvidersOpenIDConnect{
AccessTokenLifespan: time.Hour, AccessTokenLifespan: time.Hour,
AuthorizeCodeLifespan: time.Minute, AuthorizeCodeLifespan: time.Minute,
IDTokenLifespan: time.Hour, IDTokenLifespan: time.Hour,
@ -119,7 +119,7 @@ var DefaultOpenIDConnectConfiguration = OpenIDConnect{
var defaultOIDCClientConsentPreConfiguredDuration = time.Hour * 24 * 7 var defaultOIDCClientConsentPreConfiguredDuration = time.Hour * 24 * 7
// DefaultOpenIDConnectClientConfiguration contains defaults for OIDC Clients. // DefaultOpenIDConnectClientConfiguration contains defaults for OIDC Clients.
var DefaultOpenIDConnectClientConfiguration = OpenIDConnectClient{ var DefaultOpenIDConnectClientConfiguration = IdentityProvidersOpenIDConnectClient{
Policy: "two_factor", Policy: "two_factor",
Scopes: []string{"openid", "groups", "profile", "email"}, Scopes: []string{"openid", "groups", "profile", "email"},
ResponseTypes: []string{"code"}, ResponseTypes: []string{"code"},

View File

@ -132,22 +132,21 @@ var Keys = []string{
"authentication_backend.ldap.permit_feature_detection_failure", "authentication_backend.ldap.permit_feature_detection_failure",
"authentication_backend.ldap.user", "authentication_backend.ldap.user",
"authentication_backend.ldap.password", "authentication_backend.ldap.password",
"session.secret",
"session.name", "session.name",
"session.domain",
"session.same_site", "session.same_site",
"session.expiration", "session.expiration",
"session.inactivity", "session.inactivity",
"session.remember_me", "session.remember_me",
"session", "session",
"session.secret",
"session.cookies", "session.cookies",
"session.cookies[].name", "session.cookies[].name",
"session.cookies[].domain",
"session.cookies[].same_site", "session.cookies[].same_site",
"session.cookies[].expiration", "session.cookies[].expiration",
"session.cookies[].inactivity", "session.cookies[].inactivity",
"session.cookies[].remember_me", "session.cookies[].remember_me",
"session.cookies[]", "session.cookies[]",
"session.cookies[].domain",
"session.cookies[].authelia_url", "session.cookies[].authelia_url",
"session.redis.host", "session.redis.host",
"session.redis.port", "session.redis.port",
@ -165,11 +164,12 @@ var Keys = []string{
"session.redis.high_availability.sentinel_name", "session.redis.high_availability.sentinel_name",
"session.redis.high_availability.sentinel_username", "session.redis.high_availability.sentinel_username",
"session.redis.high_availability.sentinel_password", "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",
"session.redis.high_availability.nodes[].host", "session.redis.high_availability.nodes[].host",
"session.redis.high_availability.nodes[].port", "session.redis.high_availability.nodes[].port",
"session.redis.high_availability.route_by_latency", "session.domain",
"session.redis.high_availability.route_randomly",
"totp.disable", "totp.disable",
"totp.issuer", "totp.issuer",
"totp.algorithm", "totp.algorithm",
@ -264,8 +264,6 @@ var Keys = []string{
"server.address", "server.address",
"server.asset_path", "server.asset_path",
"server.disable_healthcheck", "server.disable_healthcheck",
"server.disable_autho_https_redirect",
"server.use_ip_for_ban",
"server.tls.certificate", "server.tls.certificate",
"server.tls.key", "server.tls.key",
"server.tls.client_certificates", "server.tls.client_certificates",
@ -276,8 +274,6 @@ var Keys = []string{
"server.endpoints.authz.*.implementation", "server.endpoints.authz.*.implementation",
"server.endpoints.authz.*.authn_strategies", "server.endpoints.authz.*.authn_strategies",
"server.endpoints.authz.*.authn_strategies[].name", "server.endpoints.authz.*.authn_strategies[].name",
"server.grpc.address",
"server.grpc.disableTLS",
"server.buffers.read", "server.buffers.read",
"server.buffers.write", "server.buffers.write",
"server.timeouts.read", "server.timeouts.read",

View File

@ -1,15 +1,15 @@
package schema package schema
// LogConfiguration represents the logging configuration. // Log represents the logging configuration.
type LogConfiguration struct { type Log struct {
Level string `koanf:"level"` 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"` 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"` 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"` 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. // DefaultLoggingConfiguration is the default logging configuration.
var DefaultLoggingConfiguration = LogConfiguration{ var DefaultLoggingConfiguration = Log{
Level: "info", Level: "info",
Format: "text", Format: "text",
} }

View File

@ -7,49 +7,49 @@ import (
"time" "time"
) )
// FileSystemNotifierConfiguration represents the configuration of the notifier writing emails in a file. // Notifier represents the configuration of the notifier to use when sending notifications to users.
type FileSystemNotifierConfiguration struct { type Notifier struct {
Filename string `koanf:"filename"` 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. // NotifierFileSystem represents the configuration of the notifier writing emails in a file.
type SMTPNotifierConfiguration struct { type NotifierFileSystem struct {
Address *AddressSMTP `koanf:"address"` Filename string `koanf:"filename" json:"filename" jsonschema:"title=Filename" jsonschema_description:"The file path of the notifications"`
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"`
} }
// NotifierConfiguration represents the configuration of the notifier to use when sending notifications to users. // NotifierSMTP represents the configuration of the SMTP server to send emails with.
type NotifierConfiguration struct { type NotifierSMTP struct {
DisableStartupCheck bool `koanf:"disable_startup_check"` Address *AddressSMTP `koanf:"address" json:"address" jsonschema:"default=smtp://localhost:25,title=Address" jsonschema_description:"The SMTP server address"`
FileSystem *FileSystemNotifierConfiguration `koanf:"filesystem"` Timeout time.Duration `koanf:"timeout" json:"timeout" jsonschema:"default=5 seconds,title=Timeout" jsonschema_description:"The SMTP server connection timeout"`
SMTP *SMTPNotifierConfiguration `koanf:"smtp"` Username string `koanf:"username" json:"username" jsonschema:"title=Username" jsonschema_description:"The username for SMTP authentication"`
TemplatePath string `koanf:"template_path"` 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. // 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"}}}, Address: &AddressSMTP{Address{true, false, -1, 25, &url.URL{Scheme: AddressSchemeSMTP, Host: "localhost:25"}}},
Timeout: time.Second * 5, Timeout: time.Second * 5,
Subject: "[Authelia] {title}", Subject: "[Authelia] {title}",
Identifier: "localhost", Identifier: "localhost",
StartupCheckAddress: mail.Address{Name: "Authelia Test", Address: "test@authelia.com"}, StartupCheckAddress: mail.Address{Name: "Authelia Test", Address: "test@authelia.com"},
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }

View File

@ -5,17 +5,17 @@ import (
"time" "time"
) )
// NTPConfiguration represents the configuration related to ntp server. // NTP represents the configuration related to ntp server.
type NTPConfiguration struct { type NTP struct {
Address *AddressUDP `koanf:"address"` Address *AddressUDP `koanf:"address" json:"address"`
Version int `koanf:"version"` 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"` 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"` 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"` 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. // 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"}}}, Address: &AddressUDP{Address{valid: true, socket: false, port: 123, url: &url.URL{Scheme: AddressSchemeUDP, Host: "time.cloudflare.com:123"}}},
Version: 4, Version: 4,
MaximumDesync: time.Second * 3, MaximumDesync: time.Second * 3,

View File

@ -1,37 +1,35 @@
package schema package schema
// PasswordPolicyStandardParams represents the configuration related to standard parameters of password policy. // PasswordPolicy represents the configuration related to password policy.
type PasswordPolicyStandardParams struct { type PasswordPolicy struct {
Enabled bool `koanf:"enabled"` Standard PasswordPolicyStandard `koanf:"standard" json:"standard" jsonschema:"title=Standard" jsonschema_description:"The standard password policy engine"`
MinLength int `koanf:"min_length"` ZXCVBN PasswordPolicyZXCVBN `koanf:"zxcvbn" json:"zxcvbn" jsonschema:"title=ZXCVBN" jsonschema_description:"The ZXCVBN password policy engine"`
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"`
} }
// PasswordPolicyZXCVBNParams represents the configuration related to ZXCVBN parameters of password policy. // PasswordPolicyStandard represents the configuration related to standard parameters of password policy.
type PasswordPolicyZXCVBNParams struct { type PasswordPolicyStandard struct {
Enabled bool `koanf:"enabled"` Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the standard password policy engine"`
MinScore int `koanf:"min_score"` 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. // PasswordPolicyZXCVBN represents the configuration related to ZXCVBN parameters of password policy.
type PasswordPolicyConfiguration struct { type PasswordPolicyZXCVBN struct {
Standard PasswordPolicyStandardParams `koanf:"standard"` Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the ZXCVBN password policy engine"`
ZXCVBN PasswordPolicyZXCVBNParams `koanf:"zxcvbn"` 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. // DefaultPasswordPolicyConfiguration is the default password policy configuration.
var DefaultPasswordPolicyConfiguration = PasswordPolicyConfiguration{ var DefaultPasswordPolicyConfiguration = PasswordPolicy{
Standard: PasswordPolicyStandardParams{ Standard: PasswordPolicyStandard{
Enabled: false,
MinLength: 8, MinLength: 8,
MaxLength: 0, MaxLength: 0,
}, },
ZXCVBN: PasswordPolicyZXCVBNParams{ ZXCVBN: PasswordPolicyZXCVBN{
Enabled: false,
MinScore: 3, MinScore: 3,
}, },
} }

View File

@ -6,7 +6,7 @@ import (
// PrivacyPolicy is the privacy policy configuration. // PrivacyPolicy is the privacy policy configuration.
type PrivacyPolicy struct { type PrivacyPolicy struct {
Enabled bool `koanf:"enabled"` Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the Privacy Policy functionality"`
RequireUserAcceptance bool `koanf:"require_user_acceptance"` 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"` 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" "time"
) )
// RegulationConfiguration represents the configuration related to regulation. // Regulation represents the configuration related to regulation.
type RegulationConfiguration struct { type Regulation struct {
MaxRetries int `koanf:"max_retries"` 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,weak"` 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,weak"` 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. // DefaultRegulationConfiguration represents default configuration parameters for the regulator.
var DefaultRegulationConfiguration = RegulationConfiguration{ var DefaultRegulationConfiguration = Regulation{
MaxRetries: 3, MaxRetries: 3,
FindTime: time.Minute * 2, FindTime: time.Minute * 2,
BanTime: time.Minute * 5, BanTime: time.Minute * 5,

View File

@ -5,75 +5,63 @@ import (
"time" "time"
) )
// ServerConfiguration represents the configuration of the http server. // Server represents the configuration of the http server.
type ServerConfiguration struct { type Server struct {
Address *AddressTCP `koanf:"address"` Address *AddressTCP `koanf:"address" json:"address" jsonschema:"default=tcp://:9091/,title=Address" jsonschema_description:"The address to listen on"`
AssetPath string `koanf:"asset_path"` 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"` DisableHealthcheck bool `koanf:"disable_healthcheck" json:"disable_healthcheck" jsonschema:"default=false,title=Disable Healthcheck" jsonschema_description:"Disables the healthcheck functionality"`
DisableAutoHttpsRedirect bool `koanf:"disable_autho_https_redirect"`
UseIPInsteadOfUserForBan bool `koanf:"use_ip_for_ban"`
TLS ServerTLS `koanf:"tls"` TLS ServerTLS `koanf:"tls" json:"tls" jsonschema:"title=TLS" jsonschema_description:"The server TLS configuration"`
Headers ServerHeaders `koanf:"headers"` Headers ServerHeaders `koanf:"headers" json:"headers" jsonschema:"title=Headers" jsonschema_description:"The server headers configuration"`
Endpoints ServerEndpoints `koanf:"endpoints"` Endpoints ServerEndpoints `koanf:"endpoints" json:"endpoints" jsonschema:"title=Endpoints" jsonschema_description:"The server endpoints configuration"`
GRPC ServerGRPC `koanf:"grpc"`
Buffers ServerBuffers `koanf:"buffers"` Buffers ServerBuffers `koanf:"buffers" json:"buffers" jsonschema:"title=Buffers" jsonschema_description:"The server buffers configuration"`
Timeouts ServerTimeouts `koanf:"timeouts"` Timeouts ServerTimeouts `koanf:"timeouts" json:"timeouts" jsonschema:"title=Timeouts" jsonschema_description:"The server timeouts configuration"`
// Deprecated: use address instead. // Deprecated: use address instead.
Host string `koanf:"host"` Host string `koanf:"host" json:"host" jsonschema:"deprecated"`
// Deprecated: use address instead. // Deprecated: use address instead.
Port int `koanf:"port"` Port int `koanf:"port" json:"port" jsonschema:"deprecated"`
// Deprecated: use address instead. // 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. // ServerEndpoints is the endpoints configuration for the HTTP server.
type ServerEndpoints struct { type ServerEndpoints struct {
EnablePprof bool `koanf:"enable_pprof"` 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"` 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. // ServerEndpointsAuthz is the Authz endpoints configuration for the HTTP server.
type ServerAuthzEndpoint struct { type ServerEndpointsAuthz struct {
Implementation string `koanf:"implementation"` 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. // ServerEndpointsAuthzAuthnStrategy is the Authz endpoints configuration for the HTTP server.
type ServerAuthzEndpointAuthnStrategy struct { type ServerEndpointsAuthzAuthnStrategy struct {
Name string `koanf:"name"` 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. // ServerTLS represents the configuration of the http servers TLS options.
type ServerTLS struct { type ServerTLS struct {
Certificate string `koanf:"certificate"` Certificate string `koanf:"certificate" json:"certificate" jsonschema:"title=Certificate" jsonschema_description:"Path to the Certificate"`
Key string `koanf:"key"` Key string `koanf:"key" json:"key" jsonschema:"title=Key" jsonschema_description:"Path to the Private Key"`
ClientCertificates []string `koanf:"client_certificates"` 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. // ServerHeaders represents the customization of the http server headers.
type ServerHeaders struct { 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. // DefaultServerConfiguration represents the default values of the Server.
type ServerGRPC struct { var DefaultServerConfiguration = Server{
// 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{
Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091", Path: "/"}}}, Address: &AddressTCP{Address{true, false, -1, 9091, &url.URL{Scheme: AddressSchemeTCP, Host: ":9091", Path: "/"}}},
Buffers: ServerBuffers{ Buffers: ServerBuffers{
Read: 4096, Read: 4096,
@ -85,13 +73,13 @@ var DefaultServerConfiguration = ServerConfiguration{
Idle: time.Second * 30, Idle: time.Second * 30,
}, },
Endpoints: ServerEndpoints{ Endpoints: ServerEndpoints{
Authz: map[string]ServerAuthzEndpoint{ Authz: map[string]ServerEndpointsAuthz{
"legacy": { "legacy": {
Implementation: "Legacy", Implementation: "Legacy",
}, },
"auth-request": { "auth-request": {
Implementation: "AuthRequest", Implementation: "AuthRequest",
AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{
{ {
Name: "HeaderAuthRequestProxyAuthorization", Name: "HeaderAuthRequestProxyAuthorization",
}, },
@ -102,7 +90,7 @@ var DefaultServerConfiguration = ServerConfiguration{
}, },
"forward-auth": { "forward-auth": {
Implementation: "ForwardAuth", Implementation: "ForwardAuth",
AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{
{ {
Name: "HeaderProxyAuthorization", Name: "HeaderProxyAuthorization",
}, },
@ -113,7 +101,7 @@ var DefaultServerConfiguration = ServerConfiguration{
}, },
"ext-authz": { "ext-authz": {
Implementation: "ExtAuthz", Implementation: "ExtAuthz",
AuthnStrategies: []ServerAuthzEndpointAuthnStrategy{ AuthnStrategies: []ServerEndpointsAuthzAuthnStrategy{
{ {
Name: "HeaderProxyAuthorization", Name: "HeaderProxyAuthorization",
}, },

View File

@ -6,67 +6,72 @@ import (
"time" "time"
) )
// RedisNode Represents a Node. // Session represents the configuration related to user sessions.
type RedisNode struct { type Session struct {
Host string `koanf:"host"` SessionCookieCommon `koanf:",squash"`
Port int `koanf:"port"`
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 SessionCookieCommon struct {
type RedisHighAvailabilityConfiguration struct { Name string `koanf:"name" json:"name" jsonschema:"default=authelia_session"`
SentinelName string `koanf:"sentinel_name"` SameSite string `koanf:"same_site" json:"same_site" jsonschema:"default=lax,enum=lax,enum=strict,enum=none"`
SentinelUsername string `koanf:"sentinel_username"` Expiration time.Duration `koanf:"expiration" json:"expiration" jsonschema:"default=1 hour"`
SentinelPassword string `koanf:"sentinel_password"` Inactivity time.Duration `koanf:"inactivity" json:"inactivity" jsonschema:"default=5 minutes"`
Nodes []RedisNode `koanf:"nodes"` RememberMe time.Duration `koanf:"remember_me" json:"remember_me" jsonschema:"default=30 days"`
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"`
DisableRememberMe bool DisableRememberMe bool
} }
// SessionCookieConfiguration represents the configuration for a cookie domain. // SessionCookie represents the configuration for a cookie domain.
type SessionCookieConfiguration struct { type SessionCookie struct {
SessionCookieCommonConfiguration `koanf:",squash"` 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. // DefaultSessionConfiguration is the default session configuration.
var DefaultSessionConfiguration = SessionConfiguration{ var DefaultSessionConfiguration = Session{
SessionCookieCommonConfiguration: SessionCookieCommonConfiguration{ SessionCookieCommon: SessionCookieCommon{
Name: "authelia_session", Name: "authelia_session",
Expiration: time.Hour, Expiration: time.Hour,
Inactivity: time.Minute * 5, Inactivity: time.Minute * 5,
@ -76,8 +81,18 @@ var DefaultSessionConfiguration = SessionConfiguration{
} }
// DefaultRedisConfiguration is the default redis configuration. // DefaultRedisConfiguration is the default redis configuration.
var DefaultRedisConfiguration = RedisSessionConfiguration{ var DefaultRedisConfiguration = SessionRedis{
TLS: &TLSConfig{ 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}, MinimumVersion: TLSVersion{Value: tls.VersionTLS12},
}, },
} }

View File

@ -4,42 +4,36 @@ import (
"time" "time"
) )
// TLSConfig is a representation of the TLS configuration. // TLS is a representation of the TLS configuration.
type TLSConfig struct { type TLS struct {
MinimumVersion TLSVersion `koanf:"minimum_version"` 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"` 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"` 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"` 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"` PrivateKey CryptographicPrivateKey `koanf:"private_key" json:"private_key" jsonschema:"title=Private Key" jsonschema_description:"The private key"`
CertificateChain X509CertificateChain `koanf:"certificate_chain"` CertificateChain X509CertificateChain `koanf:"certificate_chain" json:"certificate_chain" jsonschema:"title=Certificate Chain" jsonschema_description:"The certificate chain"`
}
// TLSCertificateConfig is a representation of the TLS Certificate configuration.
type TLSCertificateConfig struct {
Key CryptographicPrivateKey `koanf:"key"`
CertificateChain X509CertificateChain `koanf:"certificate_chain"`
} }
// ServerTimeouts represents server timeout configurations. // ServerTimeouts represents server timeout configurations.
type ServerTimeouts struct { type ServerTimeouts struct {
Read time.Duration `koanf:"read"` Read time.Duration `koanf:"read" json:"read" jsonschema:"default=6 seconds,title=Read" jsonschema_description:"The read timeout"`
Write time.Duration `koanf:"write"` Write time.Duration `koanf:"write" json:"write" jsonschema:"default=6 seconds,title=Write" jsonschema_description:"The write timeout"`
Idle time.Duration `koanf:"idle"` Idle time.Duration `koanf:"idle" json:"idle" jsonschema:"default=30 seconds,title=Idle" jsonschema_description:"The idle timeout"`
} }
// ServerBuffers represents server buffer configurations. // ServerBuffers represents server buffer configurations.
type ServerBuffers struct { type ServerBuffers struct {
Read int `koanf:"read"` Read int `koanf:"read" json:"read" jsonschema:"default=4096,title=Read" jsonschema_description:"The read buffer size"`
Write int `koanf:"write"` Write int `koanf:"write" json:"write" jsonschema:"default=4096,title=Write" jsonschema_description:"The write buffer size"`
} }
// JWK represents a JWK. // JWK represents a JWK.
type JWK struct { type JWK struct {
KeyID string `koanf:"key_id"` 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"` Use string `koanf:"use" json:"use" jsonschema:"default=sig,enum=sig,title=Use" jsonschema_description:"The Use of this JWK"`
Algorithm string `koanf:"algorithm"` 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"` 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"` 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" "time"
) )
// LocalStorageConfiguration represents the configuration when using local storage. // Storage represents the configuration of the storage backend.
type LocalStorageConfiguration struct { type Storage struct {
Path string `koanf:"path"` 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. // StorageLocal represents the configuration when using local storage.
type SQLStorageConfiguration struct { type StorageLocal struct {
Address *AddressTCP `koanf:"address"` Path string `koanf:"path" json:"path" jsonschema:"title=Path" jsonschema_description:"The Path for the SQLite3 database file"`
Database string `koanf:"database"` }
Username string `koanf:"username"`
Password string `koanf:"password"` // StorageSQL represents the configuration of the SQL database.
Timeout time.Duration `koanf:"timeout"` 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. // Deprecated: use address instead.
Host string `koanf:"host"` Host string `koanf:"host" json:"host" jsonschema:"deprecated"`
// Deprecated: use address instead. // Deprecated: use address instead.
Port int `koanf:"port"` Port int `koanf:"port" json:"port" jsonschema:"deprecated"`
} }
// MySQLStorageConfiguration represents the configuration of a MySQL database. // StorageMySQL represents the configuration of a MySQL database.
type MySQLStorageConfiguration struct { type StorageMySQL struct {
SQLStorageConfiguration `koanf:",squash"` StorageSQL `koanf:",squash"`
TLS *TLSConfig `koanf:"tls"` TLS *TLS `koanf:"tls" json:"tls"`
} }
// PostgreSQLStorageConfiguration represents the configuration of a PostgreSQL database. // StoragePostgreSQL represents the configuration of a PostgreSQL database.
type PostgreSQLStorageConfiguration struct { type StoragePostgreSQL struct {
SQLStorageConfiguration `koanf:",squash"` StorageSQL `koanf:",squash"`
Schema string `koanf:"schema"` 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. // StoragePostgreSQLSSL represents the SSL configuration of a PostgreSQL database.
type PostgreSQLSSLStorageConfiguration struct { type StoragePostgreSQLSSL struct {
Mode string `koanf:"mode"` Mode string `koanf:"mode" json:"mode" jsonschema:"deprecated"`
RootCertificate string `koanf:"root_certificate"` RootCertificate string `koanf:"root_certificate" json:"root_certificate" jsonschema:"deprecated"`
Certificate string `koanf:"certificate"` Certificate string `koanf:"certificate" json:"certificate" jsonschema:"deprecated"`
Key string `koanf:"key"` Key string `koanf:"key" json:"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"`
} }
// DefaultSQLStorageConfiguration represents the default SQL configuration. // DefaultSQLStorageConfiguration represents the default SQL configuration.
var DefaultSQLStorageConfiguration = SQLStorageConfiguration{ var DefaultSQLStorageConfiguration = StorageSQL{
Timeout: 5 * time.Second, Timeout: 5 * time.Second,
} }
// DefaultMySQLStorageConfiguration represents the default MySQL configuration. // DefaultMySQLStorageConfiguration represents the default MySQL configuration.
var DefaultMySQLStorageConfiguration = MySQLStorageConfiguration{ var DefaultMySQLStorageConfiguration = StorageMySQL{
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
} }
// DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration. // DefaultPostgreSQLStorageConfiguration represents the default PostgreSQL configuration.
var DefaultPostgreSQLStorageConfiguration = PostgreSQLStorageConfiguration{ var DefaultPostgreSQLStorageConfiguration = StoragePostgreSQL{
SQLStorageConfiguration: SQLStorageConfiguration{ StorageSQL: StorageSQL{
Address: &AddressTCP{Address{true, false, -1, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}}, Address: &AddressTCP{Address{true, false, -1, 5432, &url.URL{Scheme: AddressSchemeTCP, Host: "localhost:5432"}}},
}, },
Schema: "public", Schema: "public",
TLS: &TLSConfig{ TLS: &TLS{
MinimumVersion: TLSVersion{tls.VersionTLS12}, MinimumVersion: TLSVersion{tls.VersionTLS12},
}, },
SSL: &PostgreSQLSSLStorageConfiguration{ SSL: &StoragePostgreSQLSSL{
Mode: "disable", Mode: "disable",
}, },
} }

View File

@ -5,22 +5,23 @@ import (
"time" "time"
) )
// TelemetryConfig represents the telemetry config. // Telemetry represents the telemetry config.
type TelemetryConfig struct { type Telemetry struct {
Metrics TelemetryMetricsConfig `koanf:"metrics"` Metrics TelemetryMetrics `koanf:"metrics" json:"metrics" jsonschema:"title=Metrics" jsonschema_description:"The telemetry metrics server configuration"`
} }
// TelemetryMetricsConfig represents the telemetry metrics config. // TelemetryMetrics represents the telemetry metrics config.
type TelemetryMetricsConfig struct { type TelemetryMetrics struct {
Enabled bool `koanf:"enabled"` Enabled bool `koanf:"enabled" json:"enabled" jsonschema:"default=false,title=Enabled" jsonschema_description:"Enables the metrics server"`
Address *AddressTCP `koanf:"address"` 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"`
Timeouts ServerTimeouts `koanf:"timeouts"` 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. // DefaultTelemetryConfig is the default telemetry configuration.
var DefaultTelemetryConfig = TelemetryConfig{ var DefaultTelemetryConfig = Telemetry{
Metrics: TelemetryMetricsConfig{ Metrics: TelemetryMetrics{
Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959", Path: "/metrics"}}}, Address: &AddressTCP{Address{true, false, -1, 9959, &url.URL{Scheme: AddressSchemeTCP, Host: ":9959", Path: "/metrics"}}},
Buffers: ServerBuffers{ Buffers: ServerBuffers{
Read: 4096, Read: 4096,

View File

@ -1,20 +1,20 @@
package schema package schema
// TOTPConfiguration represents the configuration related to TOTP options. // TOTP represents the configuration related to TOTP options.
type TOTPConfiguration struct { type TOTP struct {
Disable bool `koanf:"disable"` Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the TOTP 2FA functionality"`
Issuer string `koanf:"issuer"` Issuer string `koanf:"issuer" json:"issuer" jsonschema:"default=Authelia,title=Issuer" jsonschema_description:"The issuer value for generated TOTP keys"`
Algorithm string `koanf:"algorithm"` 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"` 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"` Period uint `koanf:"period" json:"period" jsonschema:"default=30,title=Period" jsonschema_description:"The period value for generated TOTP keys"`
Skew *uint `koanf:"skew"` 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"` 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) var defaultOtpSkew = uint(1)
// DefaultTOTPConfiguration represents default configuration parameters for TOTP generation. // DefaultTOTPConfiguration represents default configuration parameters for TOTP generation.
var DefaultTOTPConfiguration = TOTPConfiguration{ var DefaultTOTPConfiguration = TOTP{
Issuer: "Authelia", Issuer: "Authelia",
Algorithm: TOTPAlgorithmSHA1, Algorithm: TOTPAlgorithmSHA1,
Digits: 6, Digits: 6,

View File

@ -10,18 +10,33 @@ import (
"crypto/x509" "crypto/x509"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"regexp"
"strings" "strings"
"time" "time"
"github.com/authelia/jsonschema"
"github.com/go-crypt/crypt" "github.com/go-crypt/crypt"
"github.com/go-crypt/crypt/algorithm" "github.com/go-crypt/crypt/algorithm"
"github.com/go-crypt/crypt/algorithm/plaintext" "github.com/go-crypt/crypt/algorithm/plaintext"
"github.com/valyala/fasthttp"
"gopkg.in/yaml.v3"
) )
var cdecoder algorithm.DecoderRegister var cdecoder algorithm.DecoderRegister
// DecodePasswordDigest returns a new PasswordDigest if it can be decoded. // DecodePasswordDigest returns a new PasswordDigest if it can be decoded.
func DecodePasswordDigest(encodedDigest string) (digest *PasswordDigest, err error) { 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 == nil {
if cdecoder, err = crypt.NewDefaultDecoder(); err != nil { if cdecoder, err = crypt.NewDefaultDecoder(); err != nil {
return nil, fmt.Errorf("failed to initialize decoder: %w", err) return nil, fmt.Errorf("failed to initialize decoder: %w", err)
@ -32,13 +47,12 @@ func DecodePasswordDigest(encodedDigest string) (digest *PasswordDigest, err err
} }
} }
var d algorithm.Digest return cdecoder.Decode(encodedDigest)
if d, err = cdecoder.Decode(encodedDigest); err != nil {
return nil, err
} }
return &PasswordDigest{Digest: d}, nil // NewPasswordDigest returns a new *PasswordDigest from an algorithm.Digest.
func NewPasswordDigest(digest algorithm.Digest) *PasswordDigest {
return &PasswordDigest{Digest: digest}
} }
// PasswordDigest is a configuration type for the crypt.Digest. // PasswordDigest is a configuration type for the crypt.Digest.
@ -46,6 +60,14 @@ type PasswordDigest struct {
algorithm.Digest 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. // IsPlainText returns true if the underlying algorithm.Digest is a *plaintext.Digest.
func (d *PasswordDigest) IsPlainText() bool { func (d *PasswordDigest) IsPlainText() bool {
if d == nil || d.Digest == nil { 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. // NewX509CertificateChain creates a new *X509CertificateChain from a given string, parsing each PEM block one by one.
func NewX509CertificateChain(in string) (chain *X509CertificateChain, err error) { func NewX509CertificateChain(in string) (chain *X509CertificateChain, err error) {
if in == "" { if in == "" {
@ -130,6 +166,19 @@ type TLSVersion struct {
Value uint16 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. // MaxVersion returns the value of this as a MaxVersion value.
func (v *TLSVersion) MaxVersion() uint16 { func (v *TLSVersion) MaxVersion() uint16 {
if v.Value == 0 { if v.Value == 0 {
@ -180,6 +229,14 @@ type X509CertificateChain struct {
certs []*x509.Certificate 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. // Thumbprint returns the Thumbprint for the first certificate.
func (c *X509CertificateChain) Thumbprint(hash crypto.Hash) []byte { func (c *X509CertificateChain) Thumbprint(hash crypto.Hash) []byte {
if len(c.certs) == 0 { if len(c.certs) == 0 {
@ -330,3 +387,160 @@ func (c *X509CertificateChain) Validate() (err error) {
return nil 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" "net/url"
"strconv" "strconv"
"strings" "strings"
"github.com/authelia/jsonschema"
) )
// NewAddress returns an *Address and error depending on the ability to parse the string as an Address. // 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 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. // AddressUDP is just a type with an underlying type of Address.
type AddressUDP struct { type AddressUDP struct {
Address 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. // AddressLDAP is just a type with an underlying type of Address.
type AddressLDAP struct { type AddressLDAP struct {
Address 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. // AddressSMTP is just a type with an underlying type of Address.
type AddressSMTP struct { type AddressSMTP struct {
Address Address
} }
func (AddressSMTP) JSONSchema() *jsonschema.Schema {
return &jsonschema.Schema{
Type: "string",
Format: "uri",
Pattern: `^((smtp|submissions?):\/\/)?([^:\/]*(:\d+)|[^:\/]+(:\d+)?)?$`,
}
}
// Address represents an address. // Address represents an address.
type Address struct { type Address struct {
valid bool valid bool
@ -154,6 +188,15 @@ type Address struct {
url *url.URL 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. // Valid returns true if the Address is valid.
func (a *Address) Valid() bool { func (a *Address) Valid() bool {
return a.valid return a.valid

View File

@ -6,19 +6,19 @@ import (
"github.com/go-webauthn/webauthn/protocol" "github.com/go-webauthn/webauthn/protocol"
) )
// WebAuthnConfiguration represents the webauthn config. // WebAuthn represents the webauthn config.
type WebAuthnConfiguration struct { type WebAuthn struct {
Disable bool `koanf:"disable"` Disable bool `koanf:"disable" json:"disable" jsonschema:"default=false,title=Disable" jsonschema_description:"Disables the WebAuthn 2FA functionality"`
DisplayName string `koanf:"display_name"` 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"` 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"` 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. // DefaultWebAuthnConfiguration describes the default values for the WebAuthn.
var DefaultWebAuthnConfiguration = WebAuthnConfiguration{ var DefaultWebAuthnConfiguration = WebAuthn{
DisplayName: "Authelia", DisplayName: "Authelia",
Timeout: time.Second * 60, Timeout: time.Second * 60,

View File

@ -22,7 +22,7 @@ func IsSubjectValid(subject string) (isValid bool) {
} }
// IsNetworkGroupValid check if a network group is valid. // 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 { for _, networks := range config.Networks {
if network != networks.Name { if network != networks.Name {
continue continue
@ -44,7 +44,7 @@ func IsNetworkValid(network string) (isValid bool) {
return true return true
} }
func ruleDescriptor(position int, rule schema.ACLRule) string { func ruleDescriptor(position int, rule schema.AccessControlRule) string {
if len(rule.Domains) == 0 { if len(rule.Domains) == 0 {
return fmt.Sprintf("#%d", position) 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 { if len(rule.Subjects) != 0 {
validator.Push(fmt.Errorf(errAccessControlRuleBypassPolicyInvalidWithSubjects, ruleDescriptor(rulePosition, rule))) 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 { if len(rule.Domains)+len(rule.DomainsRegex) == 0 {
validator.Push(fmt.Errorf(errFmtAccessControlRuleNoDomains, ruleDescriptor(rulePosition, rule))) 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 { for _, network := range rule.Networks {
if !IsNetworkValid(network) { if !IsNetworkValid(network) {
if !IsNetworkGroupValid(config, 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 _, subjectRule := range rule.Subjects {
for _, subject := range subjectRule { for _, subject := range subjectRule {
if !IsSubjectValid(subject) { 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) invalid, duplicates := validateList(rule.Methods, validACLHTTPMethodVerbs, true)
if len(invalid) != 0 { if len(invalid) != 0 {
@ -173,7 +173,7 @@ func validateMethods(rulePosition int, rule schema.ACLRule, validator *schema.St
} }
//nolint:gocyclo //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 j := 0; j < len(config.AccessControl.Rules[i].Query); j++ {
for k := 0; k < len(config.AccessControl.Rules[i].Query[j]); k++ { for k := 0; k < len(config.AccessControl.Rules[i].Query[j]); k++ {
if config.AccessControl.Rules[i].Query[j][k].Operator == "" { if config.AccessControl.Rules[i].Query[j][k].Operator == "" {

View File

@ -21,7 +21,7 @@ type AccessControl struct {
func (suite *AccessControl) SetupTest() { func (suite *AccessControl) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = &schema.Configuration{ suite.config = &schema.Configuration{
AccessControl: schema.AccessControlConfiguration{ AccessControl: schema.AccessControl{
DefaultPolicy: policyDeny, DefaultPolicy: policyDeny,
Networks: schema.DefaultACLNetwork, Networks: schema.DefaultACLNetwork,
@ -40,7 +40,7 @@ func (suite *AccessControl) TestShouldValidateCompleteConfiguration() {
func (suite *AccessControl) TestShouldValidateEitherDomainsOrDomainsRegex() { func (suite *AccessControl) TestShouldValidateEitherDomainsOrDomainsRegex() {
domainsRegex := regexp.MustCompile(`^abc.example.com$`) domainsRegex := regexp.MustCompile(`^abc.example.com$`)
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"abc.example.com"}, Domains: []string{"abc.example.com"},
Policy: "bypass", Policy: "bypass",
@ -74,7 +74,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidDefaultPolicy() {
} }
func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() { func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() {
suite.config.AccessControl.Networks = []schema.ACLNetwork{ suite.config.AccessControl.Networks = []schema.AccessControlNetwork{
{ {
Name: "internal", Name: "internal",
Networks: []string{"abc.def.ghi.jkl"}, Networks: []string{"abc.def.ghi.jkl"},
@ -90,7 +90,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() {
} }
func (suite *AccessControl) TestShouldRaiseWarningOnBadDomain() { func (suite *AccessControl) TestShouldRaiseWarningOnBadDomain() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"*example.com"}, Domains: []string{"*example.com"},
Policy: "one_factor", Policy: "one_factor",
@ -106,7 +106,7 @@ func (suite *AccessControl) TestShouldRaiseWarningOnBadDomain() {
} }
func (suite *AccessControl) TestShouldRaiseErrorWithNoRulesDefined() { func (suite *AccessControl) TestShouldRaiseErrorWithNoRulesDefined() {
suite.config.AccessControl.Rules = []schema.ACLRule{} suite.config.AccessControl.Rules = []schema.AccessControlRule{}
ValidateRules(suite.config, suite.validator) ValidateRules(suite.config, suite.validator)
@ -117,7 +117,7 @@ func (suite *AccessControl) TestShouldRaiseErrorWithNoRulesDefined() {
} }
func (suite *AccessControl) TestShouldRaiseWarningWithNoRulesDefined() { func (suite *AccessControl) TestShouldRaiseWarningWithNoRulesDefined() {
suite.config.AccessControl.Rules = []schema.ACLRule{} suite.config.AccessControl.Rules = []schema.AccessControlRule{}
suite.config.AccessControl.DefaultPolicy = policyTwoFactor suite.config.AccessControl.DefaultPolicy = policyTwoFactor
@ -130,7 +130,7 @@ func (suite *AccessControl) TestShouldRaiseWarningWithNoRulesDefined() {
} }
func (suite *AccessControl) TestShouldRaiseErrorsWithEmptyRules() { func (suite *AccessControl) TestShouldRaiseErrorsWithEmptyRules() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{}, {},
{ {
Policy: "wrong", Policy: "wrong",
@ -149,7 +149,7 @@ func (suite *AccessControl) TestShouldRaiseErrorsWithEmptyRules() {
} }
func (suite *AccessControl) TestShouldRaiseErrorInvalidPolicy() { func (suite *AccessControl) TestShouldRaiseErrorInvalidPolicy() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: testInvalid, Policy: testInvalid,
@ -165,7 +165,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidPolicy() {
} }
func (suite *AccessControl) TestShouldRaiseErrorInvalidNetwork() { func (suite *AccessControl) TestShouldRaiseErrorInvalidNetwork() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: "bypass", Policy: "bypass",
@ -182,7 +182,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidNetwork() {
} }
func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() { func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: "bypass", Policy: "bypass",
@ -199,7 +199,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidMethod() {
} }
func (suite *AccessControl) TestShouldRaiseErrorDuplicateMethod() { func (suite *AccessControl) TestShouldRaiseErrorDuplicateMethod() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: []string{"public.example.com"}, Domains: []string{"public.example.com"},
Policy: "bypass", Policy: "bypass",
@ -218,7 +218,7 @@ func (suite *AccessControl) TestShouldRaiseErrorDuplicateMethod() {
func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() { func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() {
domains := []string{"public.example.com"} domains := []string{"public.example.com"}
subjects := [][]string{{testInvalid}} subjects := [][]string{{testInvalid}}
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
@ -236,7 +236,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidSubject() {
} }
func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGroup() { func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGroup() {
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
DomainsRegex: MustCompileRegexps([]string{`^(?P<User>\w+)\.example\.com$`}), DomainsRegex: MustCompileRegexps([]string{`^(?P<User>\w+)\.example\.com$`}),
Policy: "bypass", Policy: "bypass",
@ -253,11 +253,11 @@ func (suite *AccessControl) TestShouldRaiseErrorBypassWithSubjectDomainRegexGrou
func (suite *AccessControl) TestShouldSetQueryDefaults() { func (suite *AccessControl) TestShouldSetQueryDefaults() {
domains := []string{"public.example.com"} domains := []string{"public.example.com"}
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "", Key: "example"}, {Operator: "", Key: "example"},
}, },
@ -269,7 +269,7 @@ func (suite *AccessControl) TestShouldSetQueryDefaults() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "pattern", Key: "a", Value: "^(x|y|z)$"}, {Operator: "pattern", Key: "a", Value: "^(x|y|z)$"},
}, },
@ -296,11 +296,11 @@ func (suite *AccessControl) TestShouldSetQueryDefaults() {
func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() { func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
domains := []string{"public.example.com"} domains := []string{"public.example.com"}
suite.config.AccessControl.Rules = []schema.ACLRule{ suite.config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "equal", Key: "example"}, {Operator: "equal", Key: "example"},
}, },
@ -309,7 +309,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "present"}, {Operator: "present"},
}, },
@ -318,7 +318,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "present", Key: "a"}, {Operator: "present", Key: "a"},
}, },
@ -327,7 +327,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "absent", Key: "a"}, {Operator: "absent", Key: "a"},
}, },
@ -336,7 +336,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{}, {},
}, },
@ -345,7 +345,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "not", Key: "a", Value: "a"}, {Operator: "not", Key: "a", Value: "a"},
}, },
@ -354,7 +354,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "pattern", Key: "a", Value: "(bad pattern"}, {Operator: "pattern", Key: "a", Value: "(bad pattern"},
}, },
@ -363,7 +363,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "present", Key: "a", Value: "not good"}, {Operator: "present", Key: "a", Value: "not good"},
}, },
@ -372,7 +372,7 @@ func (suite *AccessControl) TestShouldErrorOnInvalidRulesQuery() {
{ {
Domains: domains, Domains: domains,
Policy: "bypass", Policy: "bypass",
Query: [][]schema.ACLQueryRule{ Query: [][]schema.AccessControlRuleQuery{
{ {
{Operator: "present", Key: "a", Value: 5}, {Operator: "present", Key: "a", Value: 5},
}, },
@ -399,7 +399,7 @@ func TestAccessControl(t *testing.T) {
} }
func TestShouldReturnCorrectResultsForValidNetworkGroups(t *testing.T) { func TestShouldReturnCorrectResultsForValidNetworkGroups(t *testing.T) {
config := schema.AccessControlConfiguration{ config := schema.AccessControl{
Networks: schema.DefaultACLNetwork, Networks: schema.DefaultACLNetwork,
} }

View File

@ -52,7 +52,7 @@ func ValidateAuthenticationBackend(config *schema.AuthenticationBackend, validat
} }
// validateFileAuthenticationBackend validates and updates the file authentication backend configuration. // 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 == "" { if config.Path == "" {
validator.Push(fmt.Errorf(errFmtFileAuthBackendPathNotConfigured)) validator.Push(fmt.Errorf(errFmtFileAuthBackendPathNotConfigured))
} }
@ -61,7 +61,7 @@ func validateFileAuthenticationBackend(config *schema.FileAuthenticationBackend,
} }
// ValidatePasswordConfiguration validates the file auth backend password configuration. // 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) validateFileAuthenticationBackendPasswordConfigLegacy(config)
switch { switch {
@ -81,7 +81,7 @@ func ValidatePasswordConfiguration(config *schema.Password, validator *schema.St
} }
//nolint:gocyclo // Function is well formed. //nolint:gocyclo // Function is well formed.
func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.Password, validator *schema.StructValidator) { func validateFileAuthenticationBackendPasswordConfigArgon2(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) {
switch { switch {
case config.Argon2.Variant == "": case config.Argon2.Variant == "":
config.Argon2.Variant = schema.DefaultPasswordConfig.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 { switch {
case config.SHA2Crypt.Variant == "": case config.SHA2Crypt.Variant == "":
config.SHA2Crypt.Variant = schema.DefaultPasswordConfig.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 { switch {
case config.PBKDF2.Variant == "": case config.PBKDF2.Variant == "":
config.PBKDF2.Variant = schema.DefaultPasswordConfig.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 { switch {
case config.BCrypt.Variant == "": case config.BCrypt.Variant == "":
config.BCrypt.Variant = schema.DefaultPasswordConfig.BCrypt.Variant config.BCrypt.Variant = schema.DefaultPasswordConfig.BCrypt.Variant
@ -218,7 +218,7 @@ func validateFileAuthenticationBackendPasswordConfigBCrypt(config *schema.Passwo
} }
//nolint:gocyclo //nolint:gocyclo
func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.Password, validator *schema.StructValidator) { func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.AuthenticationBackendFilePassword, validator *schema.StructValidator) {
switch { switch {
case config.SCrypt.Iterations == 0: case config.SCrypt.Iterations == 0:
config.SCrypt.Iterations = schema.DefaultPasswordConfig.SCrypt.Iterations config.SCrypt.Iterations = schema.DefaultPasswordConfig.SCrypt.Iterations
@ -265,8 +265,8 @@ func validateFileAuthenticationBackendPasswordConfigSCrypt(config *schema.Passwo
} }
} }
//nolint:gocyclo // Function is clear enough. //nolint:gocyclo,staticcheck // Function is clear enough and being used for deprecated functionality mapping.
func validateFileAuthenticationBackendPasswordConfigLegacy(config *schema.Password) { func validateFileAuthenticationBackendPasswordConfigLegacy(config *schema.AuthenticationBackendFilePassword) {
switch config.Algorithm { switch config.Algorithm {
case hashLegacySHA512: case hashLegacySHA512:
config.Algorithm = hashSHA2Crypt config.Algorithm = hashSHA2Crypt
@ -325,7 +325,7 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val
defaultTLS.ServerName = validateLDAPAuthenticationAddress(config.LDAP, validator) defaultTLS.ServerName = validateLDAPAuthenticationAddress(config.LDAP, validator)
if config.LDAP.TLS == nil { if config.LDAP.TLS == nil {
config.LDAP.TLS = &schema.TLSConfig{} config.LDAP.TLS = &schema.TLS{}
} }
if err := ValidateTLSConfig(config.LDAP.TLS, defaultTLS); err != nil { if err := ValidateTLSConfig(config.LDAP.TLS, defaultTLS); err != nil {
@ -347,8 +347,8 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val
validateLDAPRequiredParameters(config, validator) validateLDAPRequiredParameters(config, validator)
} }
func validateLDAPAuthenticationBackendImplementation(config *schema.AuthenticationBackend, validator *schema.StructValidator) *schema.TLSConfig { func validateLDAPAuthenticationBackendImplementation(config *schema.AuthenticationBackend, validator *schema.StructValidator) *schema.TLS {
var implementation *schema.LDAPAuthenticationBackend var implementation *schema.AuthenticationBackendLDAP
switch config.LDAP.Implementation { switch config.LDAP.Implementation {
case schema.LDAPImplementationCustom: case schema.LDAPImplementationCustom:
@ -367,14 +367,14 @@ func validateLDAPAuthenticationBackendImplementation(config *schema.Authenticati
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendOptionMustBeOneOf, "implementation", strJoinOr(validLDAPImplementations), config.LDAP.Implementation)) validator.Push(fmt.Errorf(errFmtLDAPAuthBackendOptionMustBeOneOf, "implementation", strJoinOr(validLDAPImplementations), config.LDAP.Implementation))
} }
tlsconfig := &schema.TLSConfig{} tlsconfig := &schema.TLS{}
if implementation != nil { if implementation != nil {
if config.LDAP.Timeout == 0 { if config.LDAP.Timeout == 0 {
config.LDAP.Timeout = implementation.Timeout config.LDAP.Timeout = implementation.Timeout
} }
tlsconfig = &schema.TLSConfig{ tlsconfig = &schema.TLS{
MinimumVersion: implementation.TLS.MinimumVersion, MinimumVersion: implementation.TLS.MinimumVersion,
MaximumVersion: implementation.TLS.MaximumVersion, MaximumVersion: implementation.TLS.MaximumVersion,
} }
@ -389,7 +389,7 @@ func ldapImplementationShouldSetStr(config, implementation string) bool {
return config == "" && implementation != "" 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) { if ldapImplementationShouldSetStr(config.AdditionalUsersDN, implementation.AdditionalUsersDN) {
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 { if config.Address == nil {
validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "address")) validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "address"))

View File

@ -17,8 +17,8 @@ func TestShouldRaiseErrorWhenBothBackendsProvided(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
backendConfig := schema.AuthenticationBackend{} backendConfig := schema.AuthenticationBackend{}
backendConfig.LDAP = &schema.LDAPAuthenticationBackend{} backendConfig.LDAP = &schema.AuthenticationBackendLDAP{}
backendConfig.File = &schema.FileAuthenticationBackend{ backendConfig.File = &schema.AuthenticationBackendFile{
Path: "/tmp", Path: "/tmp",
} }
@ -55,7 +55,7 @@ func (suite *FileBasedAuthenticationBackend) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} 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() { func (suite *FileBasedAuthenticationBackend) TestShouldValidateCompleteConfiguration() {
@ -77,33 +77,33 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenNoPathProvi
} }
func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultConfigurationWhenBlank() { 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("", suite.config.File.Password.Algorithm)
suite.Equal(0, suite.config.File.Password.Memory) suite.Equal(0, suite.config.File.Password.KeyLength) //nolint:staticcheck
suite.Equal(0, suite.config.File.Password.Parallelism) 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) ValidateAuthenticationBackend(&suite.config, suite.validator)
suite.Len(suite.validator.Warnings(), 0) suite.Len(suite.validator.Warnings(), 0)
suite.Len(suite.validator.Errors(), 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.Algorithm, suite.config.File.Password.Algorithm)
suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) suite.Equal(schema.DefaultPasswordConfig.KeyLength, suite.config.File.Password.KeyLength) //nolint:staticcheck
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) TestShouldMigrateLegacyConfigurationSHA512() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password = schema.Password{ suite.config.File.Password = schema.AuthenticationBackendFilePassword{
Algorithm: digestSHA512, Algorithm: digestSHA512,
Iterations: 1000000, Iterations: 1000000,
SaltLength: 8, SaltLength: 8,
@ -121,14 +121,14 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512ButNotOverride() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512ButNotOverride() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password = schema.Password{ suite.config.File.Password = schema.AuthenticationBackendFilePassword{
Algorithm: digestSHA512, Algorithm: digestSHA512,
Iterations: 1000000, Iterations: 1000000,
SaltLength: 8, SaltLength: 8,
SHA2Crypt: schema.SHA2CryptPassword{ SHA2Crypt: schema.AuthenticationBackendFilePasswordSHA2Crypt{
Variant: digestSHA256, Variant: digestSHA256,
Iterations: 50000, Iterations: 50000,
SaltLength: 12, SaltLength: 12,
@ -147,10 +147,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512Alt() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationSHA512Alt() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password = schema.Password{ suite.config.File.Password = schema.AuthenticationBackendFilePassword{
Algorithm: digestSHA512, Algorithm: digestSHA512,
Iterations: 1000000, Iterations: 1000000,
SaltLength: 64, SaltLength: 64,
@ -168,10 +168,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password = schema.Password{ suite.config.File.Password = schema.AuthenticationBackendFilePassword{
Algorithm: "argon2id", Algorithm: "argon2id",
Iterations: 4, Iterations: 4,
Memory: 1024, Memory: 1024,
@ -195,17 +195,17 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2ButNotOverride() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationArgon2ButNotOverride() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password = schema.Password{ suite.config.File.Password = schema.AuthenticationBackendFilePassword{
Algorithm: "argon2id", Algorithm: "argon2id",
Iterations: 4, Iterations: 4,
Memory: 1024, Memory: 1024,
Parallelism: 4, Parallelism: 4,
KeyLength: 64, KeyLength: 64,
SaltLength: 64, SaltLength: 64,
Argon2: schema.Argon2Password{ Argon2: schema.AuthenticationBackendFilePasswordArgon2{
Variant: "argon2d", Variant: "argon2d",
Iterations: 1, Iterations: 1,
Memory: 2048, Memory: 2048,
@ -230,7 +230,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationWhenOnlySHA512Set() { func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfigurationWhenOnlySHA512Set() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = digestSHA512 suite.config.File.Password.Algorithm = digestSHA512
@ -246,7 +246,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldMigrateLegacyConfiguratio
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidArgon2Variant() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidArgon2Variant() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = "argon2" suite.config.File.Password.Algorithm = "argon2"
suite.config.File.Password.Argon2.Variant = testInvalid suite.config.File.Password.Argon2.Variant = testInvalid
@ -260,7 +260,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidArgon2
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptVariant() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptVariant() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = hashSHA2Crypt suite.config.File.Password.Algorithm = hashSHA2Crypt
suite.config.File.Password.SHA2Crypt.Variant = testInvalid suite.config.File.Password.SHA2Crypt.Variant = testInvalid
@ -274,7 +274,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2Cr
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptSaltLength() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2CryptSaltLength() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = hashSHA2Crypt suite.config.File.Password.Algorithm = hashSHA2Crypt
suite.config.File.Password.SHA2Crypt.SaltLength = 40 suite.config.File.Password.SHA2Crypt.SaltLength = 40
@ -288,7 +288,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidSHA2Cr
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidPBKDF2Variant() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidPBKDF2Variant() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = "pbkdf2" suite.config.File.Password.Algorithm = "pbkdf2"
suite.config.File.Password.PBKDF2.Variant = testInvalid suite.config.File.Password.PBKDF2.Variant = testInvalid
@ -302,7 +302,7 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidPBKDF2
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidBCryptVariant() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorOnInvalidBCryptVariant() {
suite.config.File.Password = schema.Password{} suite.config.File.Password = schema.AuthenticationBackendFilePassword{}
suite.Equal("", suite.config.File.Password.Algorithm) suite.Equal("", suite.config.File.Password.Algorithm)
suite.config.File.Password.Algorithm = "bcrypt" suite.config.File.Password.Algorithm = "bcrypt"
suite.config.File.Password.BCrypt.Variant = testInvalid suite.config.File.Password.BCrypt.Variant = testInvalid
@ -502,10 +502,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenBadAlgorith
func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() { func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() {
suite.config.File.Password.Algorithm = "" suite.config.File.Password.Algorithm = ""
suite.config.File.Password.Iterations = 0 suite.config.File.Password.Iterations = 0 //nolint:staticcheck
suite.config.File.Password.SaltLength = 0 suite.config.File.Password.SaltLength = 0 //nolint:staticcheck
suite.config.File.Password.Memory = 0 suite.config.File.Password.Memory = 0 //nolint:staticcheck
suite.config.File.Password.Parallelism = 0 suite.config.File.Password.Parallelism = 0 //nolint:staticcheck
ValidateAuthenticationBackend(&suite.config, suite.validator) ValidateAuthenticationBackend(&suite.config, suite.validator)
@ -513,10 +513,10 @@ func (suite *FileBasedAuthenticationBackend) TestShouldSetDefaultValues() {
suite.Len(suite.validator.Errors(), 0) suite.Len(suite.validator.Errors(), 0)
suite.Equal(schema.DefaultPasswordConfig.Algorithm, suite.config.File.Password.Algorithm) suite.Equal(schema.DefaultPasswordConfig.Algorithm, suite.config.File.Password.Algorithm)
suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) suite.Equal(schema.DefaultPasswordConfig.Iterations, suite.config.File.Password.Iterations) //nolint:staticcheck
suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) suite.Equal(schema.DefaultPasswordConfig.SaltLength, suite.config.File.Password.SaltLength) //nolint:staticcheck
suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) suite.Equal(schema.DefaultPasswordConfig.Memory, suite.config.File.Password.Memory) //nolint:staticcheck
suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) suite.Equal(schema.DefaultPasswordConfig.Parallelism, suite.config.File.Password.Parallelism) //nolint:staticcheck
} }
func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenResetURLIsInvalid() { func (suite *FileBasedAuthenticationBackend) TestShouldRaiseErrorWhenResetURLIsInvalid() {
@ -571,7 +571,7 @@ type LDAPAuthenticationBackendSuite struct {
func (suite *LDAPAuthenticationBackendSuite) SetupTest() { func (suite *LDAPAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationCustom suite.config.LDAP.Implementation = schema.LDAPImplementationCustom
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -867,7 +867,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldHelpDetectNoInputPlacehol
} }
func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersion() { 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) ValidateAuthenticationBackend(&suite.config, suite.validator)
@ -878,7 +878,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldSetDefaultTLSMinimumVersi
} }
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowSSL30() { func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowSSL30() {
suite.config.LDAP.TLS = &schema.TLSConfig{ suite.config.LDAP.TLS = &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
} }
@ -949,7 +949,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldErrorOnMissingMemberOfRDN
} }
func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowTLSVerMinGreaterThanVerMax() { func (suite *LDAPAuthenticationBackendSuite) TestShouldNotAllowTLSVerMinGreaterThanVerMax() {
suite.config.LDAP.TLS = &schema.TLSConfig{ suite.config.LDAP.TLS = &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS12},
} }
@ -973,7 +973,7 @@ type ActiveDirectoryAuthenticationBackendSuite struct {
func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() { func (suite *ActiveDirectoryAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationActiveDirectory suite.config.LDAP.Implementation = schema.LDAPImplementationActiveDirectory
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -1034,7 +1034,7 @@ type RFC2307bisAuthenticationBackendSuite struct {
func (suite *RFC2307bisAuthenticationBackendSuite) SetupTest() { func (suite *RFC2307bisAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationRFC2307bis suite.config.LDAP.Implementation = schema.LDAPImplementationRFC2307bis
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -1085,7 +1085,7 @@ type FreeIPAAuthenticationBackendSuite struct {
func (suite *FreeIPAAuthenticationBackendSuite) SetupTest() { func (suite *FreeIPAAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationFreeIPA suite.config.LDAP.Implementation = schema.LDAPImplementationFreeIPA
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -1136,7 +1136,7 @@ type LLDAPAuthenticationBackendSuite struct {
func (suite *LLDAPAuthenticationBackendSuite) SetupTest() { func (suite *LLDAPAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationLLDAP suite.config.LDAP.Implementation = schema.LDAPImplementationLLDAP
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -1187,7 +1187,7 @@ type GLAuthAuthenticationBackendSuite struct {
func (suite *GLAuthAuthenticationBackendSuite) SetupTest() { func (suite *GLAuthAuthenticationBackendSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config = schema.AuthenticationBackend{} suite.config = schema.AuthenticationBackend{}
suite.config.LDAP = &schema.LDAPAuthenticationBackend{} suite.config.LDAP = &schema.AuthenticationBackendLDAP{}
suite.config.LDAP.Implementation = schema.LDAPImplementationGLAuth suite.config.LDAP.Implementation = schema.LDAPImplementationGLAuth
suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress} suite.config.LDAP.Address = &schema.AddressLDAP{Address: *testLDAPAddress}
suite.config.LDAP.User = testLDAPUser suite.config.LDAP.User = testLDAPUser
@ -1237,7 +1237,7 @@ type LDAPImplementationSuite struct {
validator *schema.StructValidator 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.Timeout, suite.config.LDAP.Timeout)
suite.Equal(expected.AdditionalUsersDN, suite.config.LDAP.AdditionalUsersDN) suite.Equal(expected.AdditionalUsersDN, suite.config.LDAP.AdditionalUsersDN)
suite.Equal(expected.AdditionalGroupsDN, suite.config.LDAP.AdditionalGroupsDN) 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) 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.Timeout, suite.config.LDAP.Timeout)
suite.NotEqual(expected.UsersFilter, suite.config.LDAP.UsersFilter) suite.NotEqual(expected.UsersFilter, suite.config.LDAP.UsersFilter)
suite.NotEqual(expected.GroupsFilter, suite.config.LDAP.GroupsFilter) suite.NotEqual(expected.GroupsFilter, suite.config.LDAP.GroupsFilter)

View File

@ -17,29 +17,29 @@ func newDefaultConfig() schema.Configuration {
config.Log.Level = "info" config.Log.Level = "info"
config.Log.Format = "text" config.Log.Format = "text"
config.JWTSecret = testJWTSecret config.JWTSecret = testJWTSecret
config.AuthenticationBackend.File = &schema.FileAuthenticationBackend{ config.AuthenticationBackend.File = &schema.AuthenticationBackendFile{
Path: "/a/path", Path: "/a/path",
} }
config.AccessControl = schema.AccessControlConfiguration{ config.AccessControl = schema.AccessControl{
DefaultPolicy: "two_factor", DefaultPolicy: "two_factor",
} }
config.Session = schema.SessionConfiguration{ config.Session = schema.Session{
Secret: "secret", Secret: "secret",
Cookies: []schema.SessionCookieConfiguration{ Cookies: []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Name: "authelia_session",
Domain: exampleDotCom,
}, },
Domain: exampleDotCom,
}, },
}, },
} }
config.Storage.EncryptionKey = testEncryptionKey config.Storage.EncryptionKey = testEncryptionKey
config.Storage.Local = &schema.LocalStorageConfiguration{ config.Storage.Local = &schema.StorageLocal{
Path: "abc", Path: "abc",
} }
config.Notifier = schema.NotifierConfiguration{ config.Notifier = schema.Notifier{
FileSystem: &schema.FileSystemNotifierConfiguration{ FileSystem: &schema.NotifierFileSystem{
Filename: "/tmp/file", Filename: "/tmp/file",
}, },
} }
@ -69,7 +69,7 @@ func TestShouldAddDefaultAccessControl(t *testing.T) {
config := newDefaultConfig() config := newDefaultConfig()
config.AccessControl.DefaultPolicy = "" config.AccessControl.DefaultPolicy = ""
config.AccessControl.Rules = []schema.ACLRule{ config.AccessControl.Rules = []schema.AccessControlRule{
{ {
Policy: "bypass", Policy: "bypass",
Domains: []string{ Domains: []string{
@ -179,7 +179,7 @@ func TestValidateDefault2FAMethod(t *testing.T) {
desc: "ShouldAllowConfiguredMethodTOTP", desc: "ShouldAllowConfiguredMethodTOTP",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "totp", Default2FAMethod: "totp",
DuoAPI: schema.DuoAPIConfiguration{ DuoAPI: schema.DuoAPI{
SecretKey: "a key", SecretKey: "a key",
IntegrationKey: "another key", IntegrationKey: "another key",
Hostname: "none", Hostname: "none",
@ -190,7 +190,7 @@ func TestValidateDefault2FAMethod(t *testing.T) {
desc: "ShouldAllowConfiguredMethodWebAuthn", desc: "ShouldAllowConfiguredMethodWebAuthn",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "webauthn", Default2FAMethod: "webauthn",
DuoAPI: schema.DuoAPIConfiguration{ DuoAPI: schema.DuoAPI{
SecretKey: "a key", SecretKey: "a key",
IntegrationKey: "another key", IntegrationKey: "another key",
Hostname: "none", Hostname: "none",
@ -201,7 +201,7 @@ func TestValidateDefault2FAMethod(t *testing.T) {
desc: "ShouldAllowConfiguredMethodMobilePush", desc: "ShouldAllowConfiguredMethodMobilePush",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "mobile_push", Default2FAMethod: "mobile_push",
DuoAPI: schema.DuoAPIConfiguration{ DuoAPI: schema.DuoAPI{
SecretKey: "a key", SecretKey: "a key",
IntegrationKey: "another key", IntegrationKey: "another key",
Hostname: "none", Hostname: "none",
@ -212,12 +212,12 @@ func TestValidateDefault2FAMethod(t *testing.T) {
desc: "ShouldNotAllowDisabledMethodTOTP", desc: "ShouldNotAllowDisabledMethodTOTP",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "totp", Default2FAMethod: "totp",
DuoAPI: schema.DuoAPIConfiguration{ DuoAPI: schema.DuoAPI{
SecretKey: "a key", SecretKey: "a key",
IntegrationKey: "another key", IntegrationKey: "another key",
Hostname: "none", Hostname: "none",
}, },
TOTP: schema.TOTPConfiguration{Disable: true}, TOTP: schema.TOTP{Disable: true},
}, },
expectedErrs: []string{ expectedErrs: []string{
"option 'default_2fa_method' must be one of the enabled options 'webauthn' or 'mobile_push' but it's configured as 'totp'", "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", desc: "ShouldNotAllowDisabledMethodWebAuthn",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "webauthn", Default2FAMethod: "webauthn",
DuoAPI: schema.DuoAPIConfiguration{ DuoAPI: schema.DuoAPI{
SecretKey: "a key", SecretKey: "a key",
IntegrationKey: "another key", IntegrationKey: "another key",
Hostname: "none", Hostname: "none",
}, },
WebAuthn: schema.WebAuthnConfiguration{Disable: true}, WebAuthn: schema.WebAuthn{Disable: true},
}, },
expectedErrs: []string{ expectedErrs: []string{
"option 'default_2fa_method' must be one of the enabled options 'totp' or 'mobile_push' but it's configured as 'webauthn'", "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", desc: "ShouldNotAllowDisabledMethodMobilePush",
have: &schema.Configuration{ have: &schema.Configuration{
Default2FAMethod: "mobile_push", Default2FAMethod: "mobile_push",
DuoAPI: schema.DuoAPIConfiguration{Disable: true}, DuoAPI: schema.DuoAPI{Disable: true},
}, },
expectedErrs: []string{ expectedErrs: []string{
"option 'default_2fa_method' must be one of the enabled options 'totp' or 'webauthn' but it's configured as 'mobile_push'", "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 { testCases := []struct {
desc string desc string
have *schema.Configuration have *schema.Configuration
expected schema.DuoAPIConfiguration expected schema.DuoAPI
errs []string errs []string
}{ }{
{ {
desc: "ShouldDisableDuo", desc: "ShouldDisableDuo",
have: &schema.Configuration{}, have: &schema.Configuration{},
expected: schema.DuoAPIConfiguration{Disable: true}, expected: schema.DuoAPI{Disable: true},
}, },
{ {
desc: "ShouldDisableDuoConfigured", desc: "ShouldDisableDuoConfigured",
have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{Disable: true, Hostname: "example.com"}}, have: &schema.Configuration{DuoAPI: schema.DuoAPI{Disable: true, Hostname: "example.com"}},
expected: schema.DuoAPIConfiguration{Disable: true, Hostname: "example.com"}, expected: schema.DuoAPI{Disable: true, Hostname: "example.com"},
}, },
{ {
desc: "ShouldNotDisableDuo", desc: "ShouldNotDisableDuo",
have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ have: &schema.Configuration{DuoAPI: schema.DuoAPI{
Hostname: "test", Hostname: "test",
IntegrationKey: "test", IntegrationKey: "test",
SecretKey: "test", SecretKey: "test",
}}, }},
expected: schema.DuoAPIConfiguration{ expected: schema.DuoAPI{
Hostname: "test", Hostname: "test",
IntegrationKey: "test", IntegrationKey: "test",
SecretKey: "test", SecretKey: "test",
@ -42,11 +42,11 @@ func TestValidateDuo(t *testing.T) {
}, },
{ {
desc: "ShouldDetectMissingSecretKey", desc: "ShouldDetectMissingSecretKey",
have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ have: &schema.Configuration{DuoAPI: schema.DuoAPI{
Hostname: "test", Hostname: "test",
IntegrationKey: "test", IntegrationKey: "test",
}}, }},
expected: schema.DuoAPIConfiguration{ expected: schema.DuoAPI{
Hostname: "test", Hostname: "test",
IntegrationKey: "test", IntegrationKey: "test",
}, },
@ -56,11 +56,11 @@ func TestValidateDuo(t *testing.T) {
}, },
{ {
desc: "ShouldDetectMissingIntegrationKey", desc: "ShouldDetectMissingIntegrationKey",
have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ have: &schema.Configuration{DuoAPI: schema.DuoAPI{
Hostname: "test", Hostname: "test",
SecretKey: "test", SecretKey: "test",
}}, }},
expected: schema.DuoAPIConfiguration{ expected: schema.DuoAPI{
Hostname: "test", Hostname: "test",
SecretKey: "test", SecretKey: "test",
}, },
@ -70,11 +70,11 @@ func TestValidateDuo(t *testing.T) {
}, },
{ {
desc: "ShouldDetectMissingHostname", desc: "ShouldDetectMissingHostname",
have: &schema.Configuration{DuoAPI: schema.DuoAPIConfiguration{ have: &schema.Configuration{DuoAPI: schema.DuoAPI{
IntegrationKey: "test", IntegrationKey: "test",
SecretKey: "test", SecretKey: "test",
}}, }},
expected: schema.DuoAPIConfiguration{ expected: schema.DuoAPI{
IntegrationKey: "test", IntegrationKey: "test",
SecretKey: "test", SecretKey: "test",
}, },

View File

@ -22,7 +22,7 @@ func ValidateIdentityProviders(config *schema.IdentityProviders, val *schema.Str
validateOIDC(config.OIDC, val) validateOIDC(config.OIDC, val)
} }
func validateOIDC(config *schema.OpenIDConnect, val *schema.StructValidator) { func validateOIDC(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) {
if config == nil { if config == nil {
return 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 { switch {
case config.IssuerPrivateKey != nil: case config.IssuerPrivateKey != nil:
validateOIDCIssuerPrivateKey(config) 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{{ config.IssuerPrivateKeys = append([]schema.JWK{{
Algorithm: oidc.SigningAlgRSAUsingSHA256, Algorithm: oidc.SigningAlgRSAUsingSHA256,
Use: oidc.KeyUseSignature, Use: oidc.KeyUseSignature,
@ -80,7 +80,7 @@ func validateOIDCIssuerPrivateKey(config *schema.OpenIDConnect) {
}}, config.IssuerPrivateKeys...) }}, config.IssuerPrivateKeys...)
} }
func validateOIDCIssuerPrivateKeys(config *schema.OpenIDConnect, val *schema.StructValidator) { func validateOIDCIssuerPrivateKeys(config *schema.IdentityProvidersOpenIDConnect, val *schema.StructValidator) {
var ( var (
props *JWKProperties props *JWKProperties
err error 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 { switch config.IssuerPrivateKeys[i].Use {
case "": case "":
config.IssuerPrivateKeys[i].Use = props.Use 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 ( var (
checkEqualKey bool checkEqualKey bool
err error 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) { if config.AccessTokenLifespan == time.Duration(0) {
config.AccessTokenLifespan = schema.DefaultOpenIDConnectConfiguration.AccessTokenLifespan 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) validateOIDCOptionsCORSAllowedOrigins(config, validator)
if config.CORS.AllowedOriginsFromClientRedirectURIs { if config.CORS.AllowedOriginsFromClientRedirectURIs {
@ -228,7 +228,7 @@ func validateOIDCOptionsCORS(config *schema.OpenIDConnect, validator *schema.Str
validateOIDCOptionsCORSEndpoints(config, validator) 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 { for _, origin := range config.CORS.AllowedOrigins {
if origin.String() == "*" { if origin.String() == "*" {
if len(config.CORS.AllowedOrigins) != 1 { 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 _, client := range config.Clients {
for _, redirectURI := range client.RedirectURIs { for _, redirectURI := range client.RedirectURIs {
uri, err := url.ParseRequestURI(redirectURI) 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 { for _, endpoint := range config.CORS.Endpoints {
if !utils.IsStringInSlice(endpoint, validOIDCCORSEndpoints) { if !utils.IsStringInSlice(endpoint, validOIDCCORSEndpoints) {
val.Push(fmt.Errorf(errFmtOIDCCORSInvalidEndpoint, endpoint, strJoinOr(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 ( var (
errDeprecated bool 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].Public {
if config.Clients[c].Secret != nil { if config.Clients[c].Secret != nil {
val.Push(fmt.Errorf(errFmtOIDCClientPublicInvalidSecret, config.Clients[c].ID)) 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) 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 { switch {
case config.Clients[c].PublicKeys.URI != nil && len(config.Clients[c].PublicKeys.Values) != 0: case config.Clients[c].PublicKeys.URI != nil && len(config.Clients[c].PublicKeys.Values) != 0:
val.Push(fmt.Errorf(errFmtOIDCClientPublicKeysBothURIAndValuesConfigured, config.Clients[c].ID)) 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 ( var (
props *JWKProperties props *JWKProperties
err error 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 { switch config.Clients[c].PublicKeys.Values[i].Use {
case "": case "":
config.Clients[c].PublicKeys.Values[i].Use = props.Use 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 config.Clients[c].SectorIdentifier.String() != "" {
if utils.IsURLHostComponent(config.Clients[c].SectorIdentifier) || utils.IsURLHostComponentWithPort(config.Clients[c].SectorIdentifier) { if utils.IsURLHostComponent(config.Clients[c].SectorIdentifier) || utils.IsURLHostComponentWithPort(config.Clients[c].SectorIdentifier) {
return 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 { switch {
case utils.IsStringInSlice(config.Clients[c].ConsentMode, []string{"", auto}): case utils.IsStringInSlice(config.Clients[c].ConsentMode, []string{"", auto}):
if config.Clients[c].ConsentPreConfiguredDuration != nil { 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 { if len(config.Clients[c].Scopes) == 0 {
config.Clients[c].Scopes = schema.DefaultOpenIDConnectClientConfiguration.Scopes 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 { if len(config.Clients[c].ResponseTypes) == 0 {
config.Clients[c].ResponseTypes = schema.DefaultOpenIDConnectClientConfiguration.ResponseTypes 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 { if len(config.Clients[c].ResponseModes) == 0 {
config.Clients[c].ResponseModes = schema.DefaultOpenIDConnectClientConfiguration.ResponseModes 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 { if len(config.Clients[c].GrantTypes) == 0 {
validateOIDCClientGrantTypesSetDefaults(c, config) 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 { for _, responseType := range config.Clients[c].ResponseTypes {
switch responseType { switch responseType {
case oidc.ResponseTypeAuthorizationCodeFlow: 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 { for _, grantType := range config.Clients[c].GrantTypes {
switch grantType { switch grantType {
case oidc.GrantTypeImplicit: 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 ( var (
parsedRedirectURI *url.URL parsedRedirectURI *url.URL
err error 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) implcit := len(config.Clients[c].ResponseTypes) != 0 && utils.IsStringSliceContainsAll(config.Clients[c].ResponseTypes, validOIDCClientResponseTypesImplicitFlow)
switch { 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 { switch {
case config.Clients[c].TokenEndpointAuthSigningAlg == "": case config.Clients[c].TokenEndpointAuthSigningAlg == "":
config.Clients[c].TokenEndpointAuthSigningAlg = oidc.SigningAlgHMACUsingSHA256 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 { switch {
case config.TokenEndpointAuthSigningAlg == "": case config.TokenEndpointAuthSigningAlg == "":
val.Push(fmt.Errorf(errFmtOIDCClientInvalidTokenEndpointAuthSigAlgMissingPrivateKeyJWT, config.ID)) 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 { switch config.Clients[c].UserinfoSigningKeyID {
case "": case "":
if config.Clients[c].UserinfoSigningAlg == "" { 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) { func TestShouldRaiseErrorOnInvalidLoggingLevel(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
Log: schema.LogConfiguration{ Log: schema.Log{
Level: "TRACE", Level: "TRACE",
}, },
} }

View File

@ -8,7 +8,7 @@ import (
) )
// ValidateNotifier validates and update notifier configuration. // 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 { if config.SMTP == nil && config.FileSystem == nil {
validator.Push(fmt.Errorf(errFmtNotifierNotConfigured)) validator.Push(fmt.Errorf(errFmtNotifierNotConfigured))
@ -32,7 +32,7 @@ func ValidateNotifier(config *schema.NotifierConfiguration, validator *schema.St
validateNotifierTemplates(config, validator) validateNotifierTemplates(config, validator)
} }
func validateNotifierTemplates(config *schema.NotifierConfiguration, validator *schema.StructValidator) { func validateNotifierTemplates(config *schema.Notifier, validator *schema.StructValidator) {
if config.TemplatePath == "" { if config.TemplatePath == "" {
return 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) validateSMTPNotifierAddress(config, validator)
if config.StartupCheckAddress.Address == "" { if config.StartupCheckAddress.Address == "" {
@ -71,10 +71,10 @@ func validateSMTPNotifier(config *schema.SMTPNotifierConfiguration, validator *s
} }
if config.TLS == nil { if config.TLS == nil {
config.TLS = &schema.TLSConfig{} config.TLS = &schema.TLS{}
} }
configDefaultTLS := &schema.TLSConfig{ configDefaultTLS := &schema.TLS{
MinimumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MinimumVersion, MinimumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MinimumVersion,
MaximumVersion: schema.DefaultSMTPNotifierConfiguration.TLS.MaximumVersion, 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.Address == nil {
if config.Host == "" && config.Port == 0 { //nolint:staticcheck if config.Host == "" && config.Port == 0 { //nolint:staticcheck
validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "address")) validator.Push(fmt.Errorf(errFmtNotifierSMTPNotConfigured, "address"))

View File

@ -16,13 +16,13 @@ import (
type NotifierSuite struct { type NotifierSuite struct {
suite.Suite suite.Suite
config schema.NotifierConfiguration config schema.Notifier
validator *schema.StructValidator validator *schema.StructValidator
} }
func (suite *NotifierSuite) SetupTest() { func (suite *NotifierSuite) SetupTest() {
suite.validator = schema.NewStructValidator() suite.validator = schema.NewStructValidator()
suite.config.SMTP = &schema.SMTPNotifierConfiguration{ suite.config.SMTP = &schema.NotifierSMTP{
Address: &schema.AddressSMTP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeSMTP, exampleDotCom, 25)}, Address: &schema.AddressSMTP{Address: schema.NewAddressFromNetworkValues(schema.AddressSchemeSMTP, exampleDotCom, 25)},
Username: "john", Username: "john",
Password: "password", Password: "password",
@ -57,7 +57,7 @@ func (suite *NotifierSuite) TestShouldEnsureEitherSMTPOrFilesystemIsProvided() {
suite.Len(suite.validator.Errors(), 0) suite.Len(suite.validator.Errors(), 0)
suite.config.FileSystem = &schema.FileSystemNotifierConfiguration{ suite.config.FileSystem = &schema.NotifierFileSystem{
Filename: "test", Filename: "test",
} }
@ -147,7 +147,7 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultStartupCheckAddress() {
func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() { func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() {
suite.config.SMTP.Address.SetHostname("google.com") 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}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS11},
} }
@ -162,7 +162,7 @@ func (suite *NotifierSuite) TestSMTPShouldDefaultTLSServerNameToHost() {
} }
func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() { func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() {
suite.config.SMTP.TLS = &schema.TLSConfig{ suite.config.SMTP.TLS = &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
} }
@ -175,7 +175,7 @@ func (suite *NotifierSuite) TestSMTPShouldErrorOnSSL30() {
} }
func (suite *NotifierSuite) TestSMTPShouldErrorOnTLSMinVerGreaterThanMaxVer() { func (suite *NotifierSuite) TestSMTPShouldErrorOnTLSMinVerGreaterThanMaxVer() {
suite.config.SMTP.TLS = &schema.TLSConfig{ suite.config.SMTP.TLS = &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10},
} }
@ -262,7 +262,7 @@ File Tests.
*/ */
func (suite *NotifierSuite) TestFileShouldEnsureFilenameIsProvided() { func (suite *NotifierSuite) TestFileShouldEnsureFilenameIsProvided() {
suite.config.SMTP = nil suite.config.SMTP = nil
suite.config.FileSystem = &schema.FileSystemNotifierConfiguration{ suite.config.FileSystem = &schema.NotifierFileSystem{
Filename: "test", Filename: "test",
} }
ValidateNotifier(&suite.config, suite.validator) ValidateNotifier(&suite.config, suite.validator)
@ -287,7 +287,7 @@ func TestNotifierSuite(t *testing.T) {
} }
func TestNotifierMiscMissingTemplateTests(t *testing.T) { func TestNotifierMiscMissingTemplateTests(t *testing.T) {
config := &schema.NotifierConfiguration{ config := &schema.Notifier{
TemplatePath: string([]byte{0x0, 0x1}), TemplatePath: string([]byte{0x0, 0x1}),
} }

View File

@ -11,7 +11,7 @@ import (
func newDefaultNTPConfig() schema.Configuration { func newDefaultNTPConfig() schema.Configuration {
return 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. // 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) { if !utils.IsBoolCountLessThanN(1, true, config.Standard.Enabled, config.ZXCVBN.Enabled) {
validator.Push(fmt.Errorf(errPasswordPolicyMultipleDefined)) validator.Push(fmt.Errorf(errPasswordPolicyMultipleDefined))
} }

View File

@ -13,26 +13,26 @@ import (
func TestValidatePasswordPolicy(t *testing.T) { func TestValidatePasswordPolicy(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
have, expected *schema.PasswordPolicyConfiguration have, expected *schema.PasswordPolicy
expectedErrs []string expectedErrs []string
}{ }{
{ {
desc: "ShouldRaiseErrorsWhenMisconfigured", desc: "ShouldRaiseErrorsWhenMisconfigured",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: -1, MinLength: -1,
}, },
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: -1, MinLength: -1,
}, },
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: 3, MinScore: 3,
}, },
@ -44,14 +44,14 @@ func TestValidatePasswordPolicy(t *testing.T) {
}, },
{ {
desc: "ShouldNotRaiseErrorsStandard", desc: "ShouldNotRaiseErrorsStandard",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: 8, MinLength: 8,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: 8, MinLength: 8,
}, },
@ -59,13 +59,13 @@ func TestValidatePasswordPolicy(t *testing.T) {
}, },
{ {
desc: "ShouldNotRaiseErrorsZXCVBN", desc: "ShouldNotRaiseErrorsZXCVBN",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: 3, MinScore: 3,
}, },
@ -73,14 +73,14 @@ func TestValidatePasswordPolicy(t *testing.T) {
}, },
{ {
desc: "ShouldSetDefaultstandard", desc: "ShouldSetDefaultstandard",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: 0, MinLength: 0,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
Standard: schema.PasswordPolicyStandardParams{ Standard: schema.PasswordPolicyStandard{
Enabled: true, Enabled: true,
MinLength: 8, MinLength: 8,
}, },
@ -88,14 +88,14 @@ func TestValidatePasswordPolicy(t *testing.T) {
}, },
{ {
desc: "ShouldRaiseErrorsZXCVBNTooLow", desc: "ShouldRaiseErrorsZXCVBNTooLow",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: -1, MinScore: -1,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: -1, MinScore: -1,
}, },
@ -106,14 +106,14 @@ func TestValidatePasswordPolicy(t *testing.T) {
}, },
{ {
desc: "ShouldRaiseErrorsZXCVBNTooHigh", desc: "ShouldRaiseErrorsZXCVBNTooHigh",
have: &schema.PasswordPolicyConfiguration{ have: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: 5, MinScore: 5,
}, },
}, },
expected: &schema.PasswordPolicyConfiguration{ expected: &schema.PasswordPolicy{
ZXCVBN: schema.PasswordPolicyZXCVBNParams{ ZXCVBN: schema.PasswordPolicyZXCVBN{
Enabled: true, Enabled: true,
MinScore: 5, MinScore: 5,
}, },

View File

@ -11,7 +11,7 @@ import (
func newDefaultRegulationConfig() schema.Configuration { func newDefaultRegulationConfig() schema.Configuration {
config := schema.Configuration{ config := schema.Configuration{
Regulation: schema.RegulationConfiguration{}, Regulation: schema.Regulation{},
} }
return config 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 { if name == legacy {
switch endpoint.Implementation { switch endpoint.Implementation {
case authzImplementationLegacy: 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)) names := make([]string, len(strategies))
for _, strategy := range strategies { for _, strategy := range strategies {

View File

@ -40,12 +40,12 @@ func TestShouldSetDefaultServerValues(t *testing.T) {
func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) { func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have schema.ServerConfiguration have schema.Server
expected schema.Address expected schema.Address
}{ }{
{ {
"ShouldParseAll", "ShouldParseAll",
schema.ServerConfiguration{ schema.Server{
Host: "abc", Host: "abc",
Port: 123, Port: 123,
Path: "subpath", Path: "subpath",
@ -54,7 +54,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
}, },
{ {
"ShouldParseHostAndPort", "ShouldParseHostAndPort",
schema.ServerConfiguration{ schema.Server{
Host: "abc", Host: "abc",
Port: 123, Port: 123,
}, },
@ -62,7 +62,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
}, },
{ {
"ShouldParseHostAndPath", "ShouldParseHostAndPath",
schema.ServerConfiguration{ schema.Server{
Host: "abc", Host: "abc",
Path: "subpath", Path: "subpath",
}, },
@ -70,7 +70,7 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
}, },
{ {
"ShouldParsePortAndPath", "ShouldParsePortAndPath",
schema.ServerConfiguration{ schema.Server{
Port: 123, Port: 123,
Path: "subpath", Path: "subpath",
}, },
@ -78,21 +78,21 @@ func TestShouldSetDefaultServerValuesWithLegacyAddress(t *testing.T) {
}, },
{ {
"ShouldParseHost", "ShouldParseHost",
schema.ServerConfiguration{ schema.Server{
Host: "abc", Host: "abc",
}, },
MustParseAddress("tcp://abc:9091/"), MustParseAddress("tcp://abc:9091/"),
}, },
{ {
"ShouldParsePort", "ShouldParsePort",
schema.ServerConfiguration{ schema.Server{
Port: 123, Port: 123,
}, },
MustParseAddress("tcp://:123/"), MustParseAddress("tcp://:123/"),
}, },
{ {
"ShouldParsePath", "ShouldParsePath",
schema.ServerConfiguration{ schema.Server{
Path: "subpath", Path: "subpath",
}, },
MustParseAddress("tcp://:9091/subpath"), MustParseAddress("tcp://:9091/subpath"),
@ -131,7 +131,7 @@ func TestShouldSetDefaultConfig(t *testing.T) {
func TestValidateSeverAddress(t *testing.T) { func TestValidateSeverAddress(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Address: &schema.AddressTCP{Address: MustParseAddress("tcp://:9091/path/")}, Address: &schema.AddressTCP{Address: MustParseAddress("tcp://:9091/path/")},
}, },
} }
@ -161,7 +161,7 @@ func TestValidateServerShouldCorrectlyIdentifyValidAddressSchemes(t *testing.T)
} }
have := &schema.Configuration{ have := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Buffers: schema.ServerBuffers{ Buffers: schema.ServerBuffers{
Read: -1, Read: -1,
Write: -1, Write: -1,
@ -204,7 +204,7 @@ func TestValidateServerShouldCorrectlyIdentifyValidAddressSchemes(t *testing.T)
func TestShouldDefaultOnNegativeValues(t *testing.T) { func TestShouldDefaultOnNegativeValues(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := &schema.Configuration{ config := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Buffers: schema.ServerBuffers{ Buffers: schema.ServerBuffers{
Read: -1, Read: -1,
Write: -1, Write: -1,
@ -232,7 +232,7 @@ func TestShouldDefaultOnNegativeValues(t *testing.T) {
func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) { func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := &schema.Configuration{ config := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Path: "app le", Path: "app le",
}, },
} }
@ -247,7 +247,7 @@ func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) {
func TestShouldRaiseOnForwardSlashInPath(t *testing.T) { func TestShouldRaiseOnForwardSlashInPath(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := &schema.Configuration{ config := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Path: "app/le", Path: "app/le",
}, },
} }
@ -420,7 +420,7 @@ func TestShouldNotUpdateConfig(t *testing.T) {
func TestServerEndpointsDevelShouldWarn(t *testing.T) { func TestServerEndpointsDevelShouldWarn(t *testing.T) {
config := &schema.Configuration{ config := &schema.Configuration{
Server: schema.ServerConfiguration{ Server: schema.Server{
Endpoints: schema.ServerEndpoints{ Endpoints: schema.ServerEndpoints{
EnablePprof: true, EnablePprof: true,
EnableExpvars: true, EnableExpvars: true,
@ -442,14 +442,14 @@ func TestServerEndpointsDevelShouldWarn(t *testing.T) {
func TestServerAuthzEndpointErrors(t *testing.T) { func TestServerAuthzEndpointErrors(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have map[string]schema.ServerAuthzEndpoint have map[string]schema.ServerEndpointsAuthz
errs []string errs []string
}{ }{
{"ShouldAllowDefaultEndpoints", schema.DefaultServerConfiguration.Endpoints.Authz, nil}, {"ShouldAllowDefaultEndpoints", schema.DefaultServerConfiguration.Endpoints.Authz, nil},
{"ShouldAllowSetDefaultEndpoints", nil, nil}, {"ShouldAllowSetDefaultEndpoints", nil, nil},
{ {
"ShouldErrorOnInvalidEndpointImplementations", "ShouldErrorOnInvalidEndpointImplementations",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"example": {Implementation: "zero"}, "example": {Implementation: "zero"},
}, },
[]string{ []string{
@ -458,7 +458,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) {
}, },
{ {
"ShouldErrorOnInvalidEndpointImplementationLegacy", "ShouldErrorOnInvalidEndpointImplementationLegacy",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"legacy": {Implementation: "zero"}, "legacy": {Implementation: "zero"},
}, },
[]string{ []string{
@ -467,15 +467,15 @@ func TestServerAuthzEndpointErrors(t *testing.T) {
}, },
{ {
"ShouldErrorOnInvalidEndpointLegacyImplementation", "ShouldErrorOnInvalidEndpointLegacyImplementation",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"legacy": {Implementation: "ExtAuthz"}, "legacy": {Implementation: "ExtAuthz"},
}, },
[]string{"server: endpoints: authz: legacy: option 'implementation' is invalid: the endpoint with the name 'legacy' must use the 'Legacy' implementation"}, []string{"server: endpoints: authz: legacy: option 'implementation' is invalid: the endpoint with the name 'legacy' must use the 'Legacy' implementation"},
}, },
{ {
"ShouldErrorOnInvalidAuthnStrategies", "ShouldErrorOnInvalidAuthnStrategies",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{{Name: "bad-name"}}}, "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{{Name: "bad-name"}}},
}, },
[]string{ []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'", "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", "ShouldErrorOnDuplicateName",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerAuthzEndpointAuthnStrategy{{Name: "CookieSession"}, {Name: "CookieSession"}}}, "example": {Implementation: "ExtAuthz", AuthnStrategies: []schema.ServerEndpointsAuthzAuthnStrategy{{Name: "CookieSession"}, {Name: "CookieSession"}}},
}, },
[]string{"server: endpoints: authz: example: authn_strategies: duplicate strategy name detected with name 'CookieSession'"}, []string{"server: endpoints: authz: example: authn_strategies: duplicate strategy name detected with name 'CookieSession'"},
}, },
{ {
"ShouldErrorOnInvalidChars", "ShouldErrorOnInvalidChars",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"/abc": {Implementation: "ForwardAuth"}, "/abc": {Implementation: "ForwardAuth"},
"/abc/": {Implementation: "ForwardAuth"}, "/abc/": {Implementation: "ForwardAuth"},
"abc/": {Implementation: "ForwardAuth"}, "abc/": {Implementation: "ForwardAuth"},
@ -515,7 +515,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) {
}, },
{ {
"ShouldErrorOnEndpointsWithDuplicatePrefix", "ShouldErrorOnEndpointsWithDuplicatePrefix",
map[string]schema.ServerAuthzEndpoint{ map[string]schema.ServerEndpointsAuthz{
"apple": {Implementation: "ForwardAuth"}, "apple": {Implementation: "ForwardAuth"},
"apple/abc": {Implementation: "ForwardAuth"}, "apple/abc": {Implementation: "ForwardAuth"},
"pear/abc": {Implementation: "ExtAuthz"}, "pear/abc": {Implementation: "ExtAuthz"},
@ -568,7 +568,7 @@ func TestServerAuthzEndpointErrors(t *testing.T) {
} }
func TestServerAuthzEndpointLegacyAsImplementationLegacyWhenBlank(t *testing.T) { func TestServerAuthzEndpointLegacyAsImplementationLegacyWhenBlank(t *testing.T) {
have := map[string]schema.ServerAuthzEndpoint{ have := map[string]schema.ServerEndpointsAuthz{
"legacy": {}, "legacy": {},
} }

View File

@ -10,7 +10,7 @@ import (
) )
// ValidateSession validates and update session configuration. // 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 == "" { if config.Name == "" {
config.Name = schema.DefaultSessionConfiguration.Name config.Name = schema.DefaultSessionConfiguration.Name
} }
@ -26,7 +26,7 @@ func ValidateSession(config *schema.SessionConfiguration, validator *schema.Stru
validateSession(config, validator) validateSession(config, validator)
} }
func validateSession(config *schema.SessionConfiguration, validator *schema.StructValidator) { func validateSession(config *schema.Session, validator *schema.StructValidator) {
if config.Expiration <= 0 { if config.Expiration <= 0 {
config.Expiration = schema.DefaultSessionConfiguration.Expiration // 1 hour. config.Expiration = schema.DefaultSessionConfiguration.Expiration // 1 hour.
} }
@ -51,27 +51,27 @@ func validateSession(config *schema.SessionConfiguration, validator *schema.Stru
cookies := len(config.Cookies) cookies := len(config.Cookies)
switch { switch {
case cookies == 0 && config.Domain != "": case cookies == 0 && config.Domain != "": //nolint:staticcheck
// Add legacy configuration to the domains list. // Add legacy configuration to the domains list.
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: config.Name, Name: config.Name,
Domain: config.Domain,
SameSite: config.SameSite, SameSite: config.SameSite,
Expiration: config.Expiration, Expiration: config.Expiration,
Inactivity: config.Inactivity, Inactivity: config.Inactivity,
RememberMe: config.RememberMe, RememberMe: config.RememberMe,
DisableRememberMe: config.DisableRememberMe, 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)) validator.Push(fmt.Errorf(errFmtSessionLegacyAndWarning))
} }
validateSessionCookieDomains(config, validator) validateSessionCookieDomains(config, validator)
} }
func validateSessionCookieDomains(config *schema.SessionConfiguration, validator *schema.StructValidator) { func validateSessionCookieDomains(config *schema.Session, validator *schema.StructValidator) {
if len(config.Cookies) == 0 { if len(config.Cookies) == 0 {
validator.Push(fmt.Errorf(errFmtSessionOptionRequired, "cookies")) validator.Push(fmt.Errorf(errFmtSessionOptionRequired, "cookies"))
} }
@ -85,7 +85,7 @@ func validateSessionCookieDomains(config *schema.SessionConfiguration, validator
validateSessionCookieName(i, config) validateSessionCookieName(i, config)
validateSessionSafeRedirection(i, config, validator) validateSessionCookiesAutheliaURL(i, config, validator)
validateSessionExpiration(i, config) validateSessionExpiration(i, config)
@ -98,7 +98,7 @@ func validateSessionCookieDomains(config *schema.SessionConfiguration, validator
} }
// validateSessionDomainName returns error if the domain name is invalid. // 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] var d = config.Cookies[i]
switch { 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 == "" { if config.Cookies[i].Name == "" {
config.Cookies[i].Name = config.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 { if config.Cookies[i].Expiration <= 0 {
config.Cookies[i].Expiration = config.Expiration 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. // 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] var d = config.Cookies[i]
if utils.IsStringInSliceF(d.Domain, domains, utils.HasDomainSuffix) { if utils.IsStringInSliceF(d.Domain, domains, utils.HasDomainSuffix) {
if utils.IsStringInSlice(d.Domain, domains) { 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. // validateSessionCookiesAutheliaURL validates the AutheliaURL.
func validateSessionSafeRedirection(index int, config *schema.SessionConfiguration, validator *schema.StructValidator) { func validateSessionCookiesAutheliaURL(index int, config *schema.Session, validator *schema.StructValidator) {
var d = config.Cookies[index] var d = config.Cookies[index]
if d.AutheliaURL != nil && d.Domain != "" && !utils.IsURISafeRedirection(d.AutheliaURL, d.Domain) { 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 { if config.Cookies[i].RememberMe <= 0 && config.Cookies[i].RememberMe != schema.RememberMeDisabled {
config.Cookies[i].RememberMe = config.RememberMe 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 config.Cookies[i].SameSite == "" {
if utils.IsStringInSlice(config.SameSite, validSessionSameSiteValues) { if utils.IsStringInSlice(config.SameSite, validSessionSameSiteValues) {
config.Cookies[i].SameSite = config.SameSite 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) 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 == "" { if config.Secret == "" {
validator.Push(fmt.Errorf(errFmtSessionSecretRequired, "redis")) validator.Push(fmt.Errorf(errFmtSessionSecretRequired, "redis"))
} }
if config.Redis.TLS != nil { if config.Redis.TLS != nil {
configDefaultTLS := &schema.TLSConfig{ configDefaultTLS := &schema.TLS{
ServerName: config.Redis.Host, ServerName: config.Redis.Host,
MinimumVersion: schema.DefaultRedisConfiguration.TLS.MinimumVersion, MinimumVersion: schema.DefaultRedisConfiguration.TLS.MinimumVersion,
MaximumVersion: schema.DefaultRedisConfiguration.TLS.MaximumVersion, 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 == "" { if config.Redis.Host == "" {
validator.Push(fmt.Errorf(errFmtSessionRedisHostRequired)) validator.Push(fmt.Errorf(errFmtSessionRedisHostRequired))
} }
@ -220,11 +220,11 @@ func validateRedis(config *schema.SessionConfiguration, validator *schema.Struct
} }
if config.Redis.MaximumActiveConnections <= 0 { 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 == "" { if config.Redis.HighAvailability.SentinelName == "" {
validator.Push(fmt.Errorf(errFmtSessionRedisSentinelMissingName)) validator.Push(fmt.Errorf(errFmtSessionRedisSentinelMissingName))
} }

View File

@ -13,11 +13,11 @@ import (
"github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/configuration/schema"
) )
func newDefaultSessionConfig() schema.SessionConfiguration { func newDefaultSessionConfig() schema.Session {
config := schema.SessionConfiguration{} config := schema.Session{}
config.Secret = testJWTSecret config.Secret = testJWTSecret
config.Domain = exampleDotCom config.Domain = exampleDotCom //nolint:staticcheck
config.Cookies = []schema.SessionCookieConfiguration{} config.Cookies = []schema.SessionCookie{}
return config return config
} }
@ -40,27 +40,30 @@ func TestShouldSetDefaultSessionValues(t *testing.T) {
func TestShouldSetDefaultSessionDomainsValues(t *testing.T) { func TestShouldSetDefaultSessionDomainsValues(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string
have schema.SessionConfiguration have schema.Session
expected schema.SessionConfiguration expected schema.Session
errs []string errs []string
}{ }{
{ {
"ShouldSetGoodDefaultValues", "ShouldSetGoodDefaultValues",
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2,
}, },
Domain: exampleDotCom,
}, },
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, 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{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Domain: exampleDotCom, SameSite: "lax", Expiration: time.Hour, Name: "authelia_session", SameSite: "lax", Expiration: time.Hour,
Inactivity: time.Minute, RememberMe: time.Hour * 2, Inactivity: time.Minute, RememberMe: time.Hour * 2,
}, },
Domain: exampleDotCom,
}, },
}, },
}, },
@ -68,29 +71,31 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) {
}, },
{ {
"ShouldNotSetBadDefaultValues", "ShouldNotSetBadDefaultValues",
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
SameSite: "BAD VALUE", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, SameSite: "BAD VALUE", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2,
}, },
Cookies: []schema.SessionCookieConfiguration{ Cookies: []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Domain: exampleDotCom, Name: "authelia_session",
Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2,
}, },
Domain: exampleDotCom,
}, },
}, },
}, },
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", SameSite: "BAD VALUE", Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, 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{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Domain: exampleDotCom, SameSite: schema.DefaultSessionConfiguration.SameSite, Name: "authelia_session", SameSite: schema.DefaultSessionConfiguration.SameSite,
Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2, Expiration: time.Hour, Inactivity: time.Minute, RememberMe: time.Hour * 2,
}, },
Domain: exampleDotCom,
}, },
}, },
}, },
@ -100,41 +105,42 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) {
}, },
{ {
"ShouldSetDefaultValuesForEachConfig", "ShouldSetDefaultValuesForEachConfig",
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute,
RememberMe: schema.RememberMeDisabled, RememberMe: schema.RememberMeDisabled,
}, },
Cookies: []schema.SessionCookieConfiguration{ Cookies: []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: exampleDotCom, Domain: exampleDotCom,
}, },
},
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Domain: "example2.com", Name: "authelia_session", SameSite: "strict", Name: "authelia_session", SameSite: "strict",
},
Domain: "example2.com",
}, },
}, },
}, },
}, schema.Session{
schema.SessionConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute, Name: "default_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute,
RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true,
}, },
Cookies: []schema.SessionCookieConfiguration{ Cookies: []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "default_session", Domain: exampleDotCom, SameSite: "lax", Name: "default_session", SameSite: "lax",
Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true,
}, },
Domain: exampleDotCom,
}, },
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Domain: "example2.com", SameSite: "strict", Name: "authelia_session", SameSite: "strict",
Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true, Expiration: time.Hour, Inactivity: time.Minute, RememberMe: schema.RememberMeDisabled, DisableRememberMe: true,
}, },
Domain: "example2.com",
}, },
}, },
}, },
@ -142,17 +148,18 @@ func TestShouldSetDefaultSessionDomainsValues(t *testing.T) {
}, },
{ {
"ShouldErrorOnEmptyConfig", "ShouldErrorOnEmptyConfig",
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "", SameSite: "", Domain: "", Name: "", SameSite: "",
}, },
Cookies: []schema.SessionCookieConfiguration{}, Domain: "",
Cookies: []schema.SessionCookie{},
}, },
schema.SessionConfiguration{ schema.Session{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute * 5, RememberMe: time.Hour * 24 * 30, Name: "authelia_session", SameSite: "lax", Expiration: time.Hour, Inactivity: time.Minute * 5, RememberMe: time.Hour * 24 * 30,
}, },
Cookies: []schema.SessionCookieConfiguration{}, Cookies: []schema.SessionCookie{},
}, },
[]string{ []string{
"session: option 'cookies' is required", "session: option 'cookies' is required",
@ -203,7 +210,7 @@ func TestShouldWarnSessionValuesWhenPotentiallyInvalid(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Domain = ".example.com" config.Domain = ".example.com" //nolint:staticcheck
ValidateSession(&config, validator) ValidateSession(&config, validator)
@ -225,7 +232,7 @@ func TestShouldHandleRedisConfigSuccessfully(t *testing.T) {
config = newDefaultSessionConfig() config = newDefaultSessionConfig()
// Set redis config because password must be set only when redis is used. // Set redis config because password must be set only when redis is used.
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.localhost", Host: "redis.localhost",
Port: 6379, Port: 6379,
Password: "password", Password: "password",
@ -243,7 +250,7 @@ func TestShouldRaiseErrorWithInvalidRedisPortLow(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "authelia-port-1", Host: "authelia-port-1",
Port: -1, Port: -1,
} }
@ -260,7 +267,7 @@ func TestShouldRaiseErrorWithInvalidRedisPortHigh(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "authelia-port-1", Host: "authelia-port-1",
Port: 65536, Port: 65536,
} }
@ -287,7 +294,7 @@ func TestShouldRaiseErrorWhenRedisIsUsedAndSecretNotSet(t *testing.T) {
config.Secret = "" config.Secret = ""
// Set redis config because password must be set only when redis is used. // Set redis config because password must be set only when redis is used.
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.localhost", Host: "redis.localhost",
Port: 6379, Port: 6379,
} }
@ -311,7 +318,7 @@ func TestShouldRaiseErrorWhenRedisHasHostnameButNoPort(t *testing.T) {
config = newDefaultSessionConfig() config = newDefaultSessionConfig()
// Set redis config because password must be set only when redis is used. // Set redis config because password must be set only when redis is used.
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.localhost", Host: "redis.localhost",
Port: 0, Port: 0,
} }
@ -327,13 +334,13 @@ func TestShouldRaiseOneErrorWhenRedisHighAvailabilityHasNodesWithNoHost(t *testi
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis", Host: "redis",
Port: 6379, Port: 6379,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "authelia-sentinel", SentinelName: "authelia-sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
Nodes: []schema.RedisNode{ Nodes: []schema.SessionRedisHighAvailabilityNode{
{ {
Port: 26379, Port: 26379,
}, },
@ -358,10 +365,10 @@ func TestShouldRaiseOneErrorWhenRedisHighAvailabilityDoesNotHaveSentinelName(t *
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis", Host: "redis",
Port: 6379, Port: 6379,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelPassword: "abc123", SentinelPassword: "abc123",
}, },
} }
@ -380,13 +387,13 @@ func TestShouldUpdateDefaultPortWhenRedisSentinelHasNodes(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis", Host: "redis",
Port: 6379, Port: 6379,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "authelia-sentinel", SentinelName: "authelia-sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
Nodes: []schema.RedisNode{ Nodes: []schema.SessionRedisHighAvailabilityNode{
{ {
Host: "node-1", Host: "node-1",
Port: 333, Port: 333,
@ -416,12 +423,12 @@ func TestShouldRaiseErrorsWhenRedisSentinelOptionsIncorrectlyConfigured(t *testi
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Secret = "" config.Secret = ""
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Port: 65536, Port: 65536,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "sentinel", SentinelName: "sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
Nodes: []schema.RedisNode{ Nodes: []schema.SessionRedisHighAvailabilityNode{
{ {
Host: "node1", Host: "node1",
Port: 26379, Port: 26379,
@ -447,12 +454,12 @@ func TestShouldRaiseErrorsWhenRedisSentinelOptionsIncorrectlyConfigured(t *testi
config = newDefaultSessionConfig() config = newDefaultSessionConfig()
config.Secret = "" config.Secret = ""
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Port: -1, Port: -1,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "sentinel", SentinelName: "sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
Nodes: []schema.RedisNode{ Nodes: []schema.SessionRedisHighAvailabilityNode{
{ {
Host: "node1", Host: "node1",
Port: 26379, Port: 26379,
@ -478,13 +485,13 @@ func TestShouldNotRaiseErrorsAndSetDefaultPortWhenRedisSentinelPortBlank(t *test
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "mysentinelHost", Host: "mysentinelHost",
Port: 0, Port: 0,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "sentinel", SentinelName: "sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
Nodes: []schema.RedisNode{ Nodes: []schema.SessionRedisHighAvailabilityNode{
{ {
Host: "node1", Host: "node1",
Port: 26379, Port: 26379,
@ -507,9 +514,9 @@ func TestShouldRaiseErrorWhenRedisHostAndHighAvailabilityNodesEmpty(t *testing.T
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Port: 26379, Port: 26379,
HighAvailability: &schema.RedisHighAvailabilityConfiguration{ HighAvailability: &schema.SessionRedisHighAvailability{
SentinelName: "sentinel", SentinelName: "sentinel",
SentinelPassword: "abc123", SentinelPassword: "abc123",
RouteByLatency: true, RouteByLatency: true,
@ -529,7 +536,7 @@ func TestShouldRaiseErrorsWhenRedisHostNotSet(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Port: 6379, Port: 6379,
} }
@ -547,10 +554,10 @@ func TestShouldSetDefaultRedisTLSOptions(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.local", Host: "redis.local",
Port: 6379, Port: 6379,
TLS: &schema.TLSConfig{}, TLS: &schema.TLS{},
} }
ValidateSession(&config, validator) ValidateSession(&config, validator)
@ -567,10 +574,10 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsSSL30(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.local", Host: "redis.local",
Port: 6379, Port: 6379,
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
}, },
} }
@ -587,10 +594,10 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T)
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Redis = &schema.RedisSessionConfiguration{ config.Redis = &schema.SessionRedis{
Host: "redis.local", Host: "redis.local",
Port: 6379, Port: 6379,
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS10},
}, },
@ -607,40 +614,32 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T)
func TestShouldRaiseErrorWhenHaveDuplicatedDomainName(t *testing.T) { func TestShouldRaiseErrorWhenHaveDuplicatedDomainName(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Domain = "" config.Domain = "" //nolint:staticcheck
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: exampleDotCom, Domain: exampleDotCom,
},
AutheliaURL: MustParseURL("https://login.example.com"), AutheliaURL: MustParseURL("https://login.example.com"),
}) })
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: exampleDotCom, Domain: exampleDotCom,
},
AutheliaURL: MustParseURL("https://login.example.com"), AutheliaURL: MustParseURL("https://login.example.com"),
}) })
ValidateSession(&config, validator) ValidateSession(&config, validator)
assert.False(t, validator.HasWarnings()) assert.False(t, validator.HasWarnings())
assert.Len(t, validator.Errors(), 1) 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) { func TestShouldRaiseErrorWhenSubdomainConflicts(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Domain = "" config.Domain = "" //nolint:staticcheck
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: exampleDotCom, Domain: exampleDotCom,
},
AutheliaURL: MustParseURL("https://login.example.com"), AutheliaURL: MustParseURL("https://login.example.com"),
}) })
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: "internal.example.com", Domain: "internal.example.com",
},
AutheliaURL: MustParseURL("https://login.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) { t.Run(tc.name, func(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Domain = "" config.Domain = "" //nolint:staticcheck
config.Cookies = []schema.SessionCookieConfiguration{ config.Cookies = []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{
Domain: tc.have, Domain: tc.have,
}, },
},
} }
ValidateSession(&config, validator) ValidateSession(&config, validator)
@ -712,13 +709,13 @@ func TestShouldRaiseErrorWhenPortalURLIsInvalid(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Domain = "" config.Domain = "" //nolint:staticcheck
config.Cookies = []schema.SessionCookieConfiguration{ config.Cookies = []schema.SessionCookie{
{ {
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: "authelia_session", Name: "authelia_session",
Domain: exampleDotCom,
}, },
Domain: exampleDotCom,
AutheliaURL: MustParseURL(tc.have)}, AutheliaURL: MustParseURL(tc.have)},
} }
@ -751,7 +748,7 @@ func TestShouldRaiseErrorWhenSameSiteSetIncorrectly(t *testing.T) {
func TestShouldNotRaiseErrorWhenSameSiteSetCorrectly(t *testing.T) { func TestShouldNotRaiseErrorWhenSameSiteSetCorrectly(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
var config schema.SessionConfiguration var config schema.Session
validOptions := []string{"none", "lax", "strict"} validOptions := []string{"none", "lax", "strict"}
@ -802,15 +799,15 @@ func TestShouldNotAllowLegacyAndModernCookiesConfig(t *testing.T) {
validator := schema.NewStructValidator() validator := schema.NewStructValidator()
config := newDefaultSessionConfig() config := newDefaultSessionConfig()
config.Cookies = append(config.Cookies, schema.SessionCookieConfiguration{ config.Cookies = append(config.Cookies, schema.SessionCookie{
SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ SessionCookieCommon: schema.SessionCookieCommon{
Name: config.Name, Name: config.Name,
Domain: config.Domain,
SameSite: config.SameSite, SameSite: config.SameSite,
Expiration: config.Expiration, Expiration: config.Expiration,
Inactivity: config.Inactivity, Inactivity: config.Inactivity,
RememberMe: config.RememberMe, RememberMe: config.RememberMe,
}, },
Domain: config.Domain, //nolint:staticcheck
}) })
ValidateSession(&config, validator) ValidateSession(&config, validator)

View File

@ -8,8 +8,8 @@ import (
"github.com/authelia/authelia/v4/internal/configuration/schema" "github.com/authelia/authelia/v4/internal/configuration/schema"
) )
// ValidateTLSConfig sets the default values and validates a schema.TLSConfig. // ValidateTLSConfig sets the default values and validates a schema.TLS.
func ValidateTLSConfig(config *schema.TLSConfig, configDefault *schema.TLSConfig) (err error) { func ValidateTLSConfig(config *schema.TLS, configDefault *schema.TLS) (err error) {
if configDefault == nil { if configDefault == nil {
return errors.New("must provide configDefault") return errors.New("must provide configDefault")
} }

View File

@ -10,16 +10,16 @@ import (
func TestValidateTLSConfig(t *testing.T) { func TestValidateTLSConfig(t *testing.T) {
var ( var (
config, configDefault *schema.TLSConfig config, configDefault *schema.TLS
) )
assert.EqualError(t, ValidateTLSConfig(config, configDefault), "must provide configDefault") assert.EqualError(t, ValidateTLSConfig(config, configDefault), "must provide configDefault")
configDefault = &schema.TLSConfig{} configDefault = &schema.TLS{}
assert.NoError(t, ValidateTLSConfig(config, configDefault)) assert.NoError(t, ValidateTLSConfig(config, configDefault))
config = &schema.TLSConfig{} config = &schema.TLS{}
assert.NoError(t, ValidateTLSConfig(config, configDefault)) assert.NoError(t, ValidateTLSConfig(config, configDefault))

View File

@ -9,7 +9,7 @@ import (
) )
// ValidateStorage validates storage configuration. // 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 { if config.Local == nil && config.MySQL == nil && config.PostgreSQL == nil {
validator.Push(errors.New(errStrStorage)) 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.Address == nil {
if config.Host == "" { //nolint:staticcheck if config.Host == "" { //nolint:staticcheck
validator.Push(fmt.Errorf(errFmtStorageOptionMustBeProvided, provider, "address")) 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) { func validateMySQLConfiguration(config *schema.StorageMySQL, validator *schema.StructValidator) {
validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "mysql") validateSQLConfiguration(&config.StorageSQL, validator, "mysql")
if config.TLS != nil { if config.TLS != nil {
configDefaultTLS := &schema.TLSConfig{ configDefaultTLS := &schema.TLS{
MinimumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MinimumVersion, MinimumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MinimumVersion,
MaximumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MaximumVersion, MaximumVersion: schema.DefaultMySQLStorageConfiguration.TLS.MaximumVersion,
} }
@ -88,18 +88,18 @@ func validateMySQLConfiguration(config *schema.MySQLStorageConfiguration, valida
} }
} }
func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfiguration, validator *schema.StructValidator) { func validatePostgreSQLConfiguration(config *schema.StoragePostgreSQL, validator *schema.StructValidator) {
validateSQLConfiguration(&config.SQLStorageConfiguration, validator, "postgres") validateSQLConfiguration(&config.StorageSQL, validator, "postgres")
if config.Schema == "" { if config.Schema == "" {
config.Schema = schema.DefaultPostgreSQLStorageConfiguration.Schema config.Schema = schema.DefaultPostgreSQLStorageConfiguration.Schema
} }
switch { switch {
case config.TLS != nil && config.SSL != nil: case config.TLS != nil && config.SSL != nil: //nolint:staticcheck
validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLAndTLSConfig)) validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLAndTLSConfig))
case config.TLS != nil: case config.TLS != nil:
configDefaultTLS := &schema.TLSConfig{ configDefaultTLS := &schema.TLS{
ServerName: config.Address.Hostname(), ServerName: config.Address.Hostname(),
MinimumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MinimumVersion, MinimumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MinimumVersion,
MaximumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MaximumVersion, MaximumVersion: schema.DefaultPostgreSQLStorageConfiguration.TLS.MaximumVersion,
@ -108,19 +108,19 @@ func validatePostgreSQLConfiguration(config *schema.PostgreSQLStorageConfigurati
if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil { if err := ValidateTLSConfig(config.TLS, configDefaultTLS); err != nil {
validator.Push(fmt.Errorf(errFmtStorageTLSConfigInvalid, "postgres", err)) validator.Push(fmt.Errorf(errFmtStorageTLSConfigInvalid, "postgres", err))
} }
case config.SSL != nil: case config.SSL != nil: //nolint:staticcheck
validator.PushWarning(fmt.Errorf(warnFmtStoragePostgreSQLInvalidSSLDeprecated)) validator.PushWarning(fmt.Errorf(warnFmtStoragePostgreSQLInvalidSSLDeprecated))
switch { switch {
case config.SSL.Mode == "": case config.SSL.Mode == "": //nolint:staticcheck
config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode config.SSL.Mode = schema.DefaultPostgreSQLStorageConfiguration.SSL.Mode //nolint:staticcheck
case !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes): case !utils.IsStringInSlice(config.SSL.Mode, validStoragePostgreSQLSSLModes): //nolint:staticcheck
validator.Push(fmt.Errorf(errFmtStoragePostgreSQLInvalidSSLMode, strJoinOr(validStoragePostgreSQLSSLModes), config.SSL.Mode)) 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 == "" { if config.Path == "" {
validator.Push(fmt.Errorf(errFmtStorageOptionMustBeProvided, "local", "path")) validator.Push(fmt.Errorf(errFmtStorageOptionMustBeProvided, "local", "path"))
} }

View File

@ -11,7 +11,7 @@ import (
type StorageSuite struct { type StorageSuite struct {
suite.Suite suite.Suite
config schema.StorageConfiguration config schema.Storage
validator *schema.StructValidator validator *schema.StructValidator
} }
@ -36,7 +36,7 @@ func (suite *StorageSuite) TestShouldValidateOneStorageIsConfigured() {
} }
func (suite *StorageSuite) TestShouldValidateLocalPathIsProvided() { func (suite *StorageSuite) TestShouldValidateLocalPathIsProvided() {
suite.config.Local = &schema.LocalStorageConfiguration{ suite.config.Local = &schema.StorageLocal{
Path: "", Path: "",
} }
@ -57,7 +57,7 @@ func (suite *StorageSuite) TestShouldValidateLocalPathIsProvided() {
} }
func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabaseAreProvided() { func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabaseAreProvided() {
suite.config.MySQL = &schema.MySQLStorageConfiguration{} suite.config.MySQL = &schema.StorageMySQL{}
ValidateStorage(suite.config, suite.validator) ValidateStorage(suite.config, suite.validator)
suite.Require().Len(suite.validator.Errors(), 3) 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.Assert().EqualError(suite.validator.Errors()[2], "storage: mysql: option 'database' is required")
suite.validator.Clear() suite.validator.Clear()
suite.config.MySQL = &schema.MySQLStorageConfiguration{ suite.config.MySQL = &schema.StorageMySQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "localhost", Host: "localhost",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
@ -81,14 +81,14 @@ func (suite *StorageSuite) TestShouldValidateMySQLHostUsernamePasswordAndDatabas
} }
func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() { func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() {
suite.config.MySQL = &schema.MySQLStorageConfiguration{ suite.config.MySQL = &schema.StorageMySQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Address: &schema.AddressTCP{Address: MustParseAddress("tcp://mysql:1234")}, Address: &schema.AddressTCP{Address: MustParseAddress("tcp://mysql:1234")},
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12},
}, },
} }
@ -103,14 +103,14 @@ func (suite *StorageSuite) TestShouldSetDefaultMySQLTLSServerName() {
} }
func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() { func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() {
suite.config.MySQL = &schema.MySQLStorageConfiguration{ suite.config.MySQL = &schema.StorageMySQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
}, },
} }
@ -124,14 +124,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSVersion() {
} }
func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreaterThanMaximum() { func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreaterThanMaximum() {
suite.config.MySQL = &schema.MySQLStorageConfiguration{ suite.config.MySQL = &schema.StorageMySQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11},
}, },
@ -146,7 +146,7 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidMySQLTLSMinVersionGreate
} }
func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDatabaseAreProvided() { func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDatabaseAreProvided() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{} suite.config.PostgreSQL = &schema.StoragePostgreSQL{}
suite.config.MySQL = nil suite.config.MySQL = nil
ValidateStorage(suite.config, suite.validator) 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.Assert().EqualError(suite.validator.Errors()[2], "storage: postgres: option 'database' is required")
suite.validator.Clear() suite.validator.Clear()
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "postgre", Host: "postgre",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
@ -171,8 +171,8 @@ func (suite *StorageSuite) TestShouldValidatePostgreSQLHostUsernamePasswordAndDa
} }
func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() { func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
@ -185,21 +185,21 @@ func (suite *StorageSuite) TestShouldValidatePostgresSchemaDefault() {
suite.Assert().Len(suite.validator.Warnings(), 0) suite.Assert().Len(suite.validator.Warnings(), 0)
suite.Assert().Len(suite.validator.Errors(), 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().Nil(suite.config.PostgreSQL.TLS)
suite.Assert().Equal("public", suite.config.PostgreSQL.Schema) suite.Assert().Equal("public", suite.config.PostgreSQL.Schema)
} }
func (suite *StorageSuite) TestShouldValidatePostgresTLSDefaults() { func (suite *StorageSuite) TestShouldValidatePostgresTLSDefaults() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{}, TLS: &schema.TLS{},
} }
ValidateStorage(suite.config, suite.validator) 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.Warnings(), 0)
suite.Assert().Len(suite.validator.Errors(), 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.Require().NotNil(suite.config.PostgreSQL.TLS)
suite.Assert().Equal(uint16(tls.VersionTLS12), suite.config.PostgreSQL.TLS.MinimumVersion.Value) suite.Assert().Equal(uint16(tls.VersionTLS12), suite.config.PostgreSQL.TLS.MinimumVersion.Value)
} }
func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() { func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "mysql1", Host: "mysql1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS12},
}, },
} }
@ -235,14 +235,14 @@ func (suite *StorageSuite) TestShouldSetDefaultPostgreSQLTLSServerName() {
} }
func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() { func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck MinimumVersion: schema.TLSVersion{Value: tls.VersionSSL30}, //nolint:staticcheck
}, },
} }
@ -256,14 +256,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLTLSVersion() {
} }
func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGreaterThanMaximum() { func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGreaterThanMaximum() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
TLS: &schema.TLSConfig{ TLS: &schema.TLS{
MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13}, MinimumVersion: schema.TLSVersion{Value: tls.VersionTLS13},
MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11}, MaximumVersion: schema.TLSVersion{Value: tls.VersionTLS11},
}, },
@ -278,14 +278,14 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnInvalidPostgreSQLMinVersionGrea
} }
func (suite *StorageSuite) TestShouldValidatePostgresSSLDefaults() { func (suite *StorageSuite) TestShouldValidatePostgresSSLDefaults() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
SSL: &schema.PostgreSQLSSLStorageConfiguration{}, SSL: &schema.StoragePostgreSQLSSL{},
} }
ValidateStorage(suite.config, suite.validator) 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.Warnings(), 1)
suite.Assert().Len(suite.validator.Errors(), 0) 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.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() { func (suite *StorageSuite) TestShouldRaiseErrorOnTLSAndLegacySSL() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
SSL: &schema.PostgreSQLSSLStorageConfiguration{}, SSL: &schema.StoragePostgreSQLSSL{},
TLS: &schema.TLSConfig{}, TLS: &schema.TLS{},
} }
ValidateStorage(suite.config, suite.validator) ValidateStorage(suite.config, suite.validator)
@ -320,15 +320,15 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnTLSAndLegacySSL() {
} }
func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfiguration() { func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfiguration() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db1", Host: "db1",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
Schema: "authelia", Schema: "authelia",
SSL: &schema.PostgreSQLSSLStorageConfiguration{ SSL: &schema.StoragePostgreSQLSSL{
Mode: "require", Mode: "require",
}, },
} }
@ -338,21 +338,21 @@ func (suite *StorageSuite) TestShouldValidatePostgresDefaultsDontOverrideConfigu
suite.Require().Len(suite.validator.Warnings(), 1) suite.Require().Len(suite.validator.Warnings(), 1)
suite.Assert().Len(suite.validator.Errors(), 0) 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().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") 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() { func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() {
suite.config.PostgreSQL = &schema.PostgreSQLStorageConfiguration{ suite.config.PostgreSQL = &schema.StoragePostgreSQL{
SQLStorageConfiguration: schema.SQLStorageConfiguration{ StorageSQL: schema.StorageSQL{
Host: "db2", Host: "db2",
Username: "myuser", Username: "myuser",
Password: "pass", Password: "pass",
Database: "database", Database: "database",
}, },
SSL: &schema.PostgreSQLSSLStorageConfiguration{ SSL: &schema.StoragePostgreSQLSSL{
Mode: "unknown", Mode: "unknown",
}, },
} }
@ -366,7 +366,7 @@ func (suite *StorageSuite) TestShouldValidatePostgresSSLModeMustBeValid() {
func (suite *StorageSuite) TestShouldRaiseErrorOnNoEncryptionKey() { func (suite *StorageSuite) TestShouldRaiseErrorOnNoEncryptionKey() {
suite.config.EncryptionKey = "" suite.config.EncryptionKey = ""
suite.config.Local = &schema.LocalStorageConfiguration{ suite.config.Local = &schema.StorageLocal{
Path: "/this/is/a/path", Path: "/this/is/a/path",
} }
@ -379,7 +379,7 @@ func (suite *StorageSuite) TestShouldRaiseErrorOnNoEncryptionKey() {
func (suite *StorageSuite) TestShouldRaiseErrorOnShortEncryptionKey() { func (suite *StorageSuite) TestShouldRaiseErrorOnShortEncryptionKey() {
suite.config.EncryptionKey = "abc" suite.config.EncryptionKey = "abc"
suite.config.Local = &schema.LocalStorageConfiguration{ suite.config.Local = &schema.StorageLocal{
Path: "/this/is/a/path", Path: "/this/is/a/path",
} }

View File

@ -35,9 +35,9 @@ func TestValidateTelemetry(t *testing.T) {
}, },
{ {
"ShouldSetDefaultPort", "ShouldSetDefaultPort",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://0.0.0.0")}}}, &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{Address: mustParseAddress("tcp://0.0.0.0")}}},
&schema.Configuration{Telemetry: schema.TelemetryConfig{ &schema.Configuration{Telemetry: schema.Telemetry{
Metrics: schema.TelemetryMetricsConfig{ Metrics: schema.TelemetryMetrics{
Address: mustParseAddress("tcp://0.0.0.0:9959/metrics"), Address: mustParseAddress("tcp://0.0.0.0:9959/metrics"),
Buffers: schema.ServerBuffers{ Buffers: schema.ServerBuffers{
Read: 4096, Read: 4096,
@ -55,22 +55,22 @@ func TestValidateTelemetry(t *testing.T) {
}, },
{ {
"ShouldSetDefaultPortAlt", "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}, &schema.Configuration{Telemetry: schema.DefaultTelemetryConfig},
nil, nil,
nil, nil,
}, },
{ {
"ShouldSetDefaultPortWithCustomIP", "ShouldSetDefaultPortWithCustomIP",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("tcp://127.0.0.1")}}}, &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{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:9959/metrics")}}},
nil, nil,
nil, nil,
}, },
{ {
"ShouldNotValidateUDP", "ShouldNotValidateUDP",
&schema.Configuration{Telemetry: schema.TelemetryConfig{Metrics: schema.TelemetryMetricsConfig{Address: mustParseAddress("udp://0.0.0.0")}}}, &schema.Configuration{Telemetry: schema.Telemetry{Metrics: schema.TelemetryMetrics{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:9959/metrics")}}},
nil, 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'"}, []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) { func TestValidateTOTP(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
have schema.TOTPConfiguration have schema.TOTP
expected schema.TOTPConfiguration expected schema.TOTP
errs []string errs []string
warns []string warns []string
}{ }{
@ -24,12 +24,12 @@ func TestValidateTOTP(t *testing.T) {
}, },
{ {
desc: "ShouldNotSetDefaultTOTPValuesWhenDisabled", desc: "ShouldNotSetDefaultTOTPValuesWhenDisabled",
have: schema.TOTPConfiguration{Disable: true}, have: schema.TOTP{Disable: true},
expected: schema.TOTPConfiguration{Disable: true}, expected: schema.TOTP{Disable: true},
}, },
{ {
desc: "ShouldNormalizeTOTPAlgorithm", desc: "ShouldNormalizeTOTPAlgorithm",
have: schema.TOTPConfiguration{ have: schema.TOTP{
Algorithm: digestSHA1, Algorithm: digestSHA1,
Digits: 6, Digits: 6,
Period: 30, Period: 30,
@ -37,7 +37,7 @@ func TestValidateTOTP(t *testing.T) {
Skew: schema.DefaultTOTPConfiguration.Skew, Skew: schema.DefaultTOTPConfiguration.Skew,
Issuer: "abc", Issuer: "abc",
}, },
expected: schema.TOTPConfiguration{ expected: schema.TOTP{
Algorithm: "SHA1", Algorithm: "SHA1",
Digits: 6, Digits: 6,
Period: 30, Period: 30,
@ -48,7 +48,7 @@ func TestValidateTOTP(t *testing.T) {
}, },
{ {
desc: "ShouldRaiseErrorWhenInvalidTOTPAlgorithm", desc: "ShouldRaiseErrorWhenInvalidTOTPAlgorithm",
have: schema.TOTPConfiguration{ have: schema.TOTP{
Algorithm: "sha3", Algorithm: "sha3",
Digits: 6, Digits: 6,
Period: 30, Period: 30,
@ -62,7 +62,7 @@ func TestValidateTOTP(t *testing.T) {
}, },
{ {
desc: "ShouldRaiseErrorWhenInvalidTOTPValue", desc: "ShouldRaiseErrorWhenInvalidTOTPValue",
have: schema.TOTPConfiguration{ have: schema.TOTP{
Algorithm: "sha3", Algorithm: "sha3",
Period: 5, Period: 5,
Digits: 20, Digits: 20,

View File

@ -190,7 +190,7 @@ func jwkCalculateThumbprint(key schema.CryptographicKey) (thumbprintStr string,
return fmt.Sprintf("%x", thumbprint)[:6], nil 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 { for _, jwk := range config.IssuerPrivateKeys {
if kid == jwk.KeyID { if kid == jwk.KeyID {
return jwk.Algorithm return jwk.Algorithm

View File

@ -81,7 +81,7 @@ func TestSchemaJWKGetPropertiesMissingTests(t *testing.T) {
} }
func TestGetResponseObjectAlgFromKID(t *testing.T) { func TestGetResponseObjectAlgFromKID(t *testing.T) {
c := &schema.OpenIDConnect{ c := &schema.IdentityProvidersOpenIDConnect{
IssuerPrivateKeys: []schema.JWK{ IssuerPrivateKeys: []schema.JWK{
{KeyID: "abc", Algorithm: "EX256"}, {KeyID: "abc", Algorithm: "EX256"},
{KeyID: "123", Algorithm: "EX512"}, {KeyID: "123", Algorithm: "EX512"},

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