feat(configuration): add error and warn log levels (#2050)
This is so levels like warn and error can be used to exclude info or warn messages. Additionally there is a reasonable refactoring of logging moving the log config options to the logging key because there are a significant number of log options now. This also decouples the expvars and pprof handlers from the log level, and they are now configured by server.enable_expvars and server.enable_pprof at any logging level.pull/1944/head^2
parent
4cfda7eece
commit
cef35fadcd
|
@ -52,11 +52,17 @@ func startServer() {
|
|||
}
|
||||
}
|
||||
|
||||
if err := logging.InitializeLogger(config.LogFormat, config.LogFilePath, config.LogKeepStdout); err != nil {
|
||||
if err := logging.InitializeLogger(config.Logging.Format, config.Logging.FilePath, config.Logging.KeepStdout); err != nil {
|
||||
logger.Fatalf("Cannot initialize logger: %v", err)
|
||||
}
|
||||
|
||||
switch config.LogLevel {
|
||||
switch config.Logging.Level {
|
||||
case "error":
|
||||
logger.Info("Logging severity set to error")
|
||||
logging.SetLevel(logrus.ErrorLevel)
|
||||
case "warn":
|
||||
logger.Info("Logging severity set to warn")
|
||||
logging.SetLevel(logrus.WarnLevel)
|
||||
case "info":
|
||||
logger.Info("Logging severity set to info")
|
||||
logging.SetLevel(logrus.InfoLevel)
|
||||
|
|
|
@ -34,17 +34,24 @@ server:
|
|||
## Must be alphanumeric chars and should not contain any slashes.
|
||||
path: ""
|
||||
|
||||
## Enables the pprof endpoint.
|
||||
enable_pprof: false
|
||||
|
||||
## Enables the expvars endpoint.
|
||||
enable_expvars: false
|
||||
|
||||
## Level of verbosity for logs: info, debug, trace.
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
## Format the logs are written as: json, text.
|
||||
# log_format: json
|
||||
# format: json
|
||||
|
||||
## File path where the logs will be written. If not set logs are written to stdout.
|
||||
# log_file_path: /config/authelia.log
|
||||
# file_path: /config/authelia.log
|
||||
|
||||
## Whether to also log to stdout when a log_file_path is defined.
|
||||
# log_keep_stdout: false
|
||||
# keep_stdout: false
|
||||
|
||||
## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be
|
||||
## set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Identity Providers
|
||||
parent: Configuration
|
||||
nav_order: 12
|
||||
nav_order: 3
|
||||
has_children: true
|
||||
---
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
layout: default
|
||||
title: Logging
|
||||
parent: Configuration
|
||||
nav_order: 4
|
||||
---
|
||||
|
||||
# Logging
|
||||
|
||||
The logging section tunes the logging settings.
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
level: info
|
||||
format: text
|
||||
file_path: ""
|
||||
keep_stdout: false
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### level
|
||||
<div markdown="1">
|
||||
type: string
|
||||
{: .label .label-config .label-purple }
|
||||
default: info
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Defines the level of logs used by Authelia. This level can be set to `trace`, `debug`, `info`, `warn`, or `error`. When
|
||||
setting level to `trace`, you will generate a large amount of log entries and expose the `/debug/vars` and
|
||||
`/debug/pprof/` endpoints which should not be enabled in production.
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
level: debug
|
||||
```
|
||||
|
||||
### format
|
||||
<div markdown="1">
|
||||
type: string
|
||||
{: .label .label-config .label-purple }
|
||||
default: text
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Defines the format of the logs written by Authelia. This format can be set to `json` or `text`.
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
format: json
|
||||
```
|
||||
|
||||
#### JSON format
|
||||
```
|
||||
{"level":"info","msg":"Logging severity set to info","time":"2020-01-01T00:00:00+11:00"}
|
||||
{"level":"info","msg":"Authelia is listening for non-TLS connections on 0.0.0.0:9091","time":"2020-01-01T00:00:00+11:00"}
|
||||
```
|
||||
#### Text format
|
||||
```
|
||||
time="2020-01-01T00:00:00+11:00" level=info msg="Logging severity set to info"
|
||||
time="2020-01-01T00:00:00+11:00" level=info msg="Authelia is listening for non-TLS connections on 0.0.0.0:9091"
|
||||
```
|
||||
|
||||
### file_path
|
||||
<div markdown="1">
|
||||
type: string (path)
|
||||
{: .label .label-config .label-purple }
|
||||
default: ""
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Logs can be stored in a file when file path is provided. Otherwise logs are written to standard output. When setting the
|
||||
level to `debug` or `trace` this will generate large amount of log entries. Administrators will need to ensure that
|
||||
they rotate and/or truncate the logs over time to prevent significant long-term disk usage.
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
file_path: /config/authelia.log
|
||||
```
|
||||
|
||||
### keep_stdout
|
||||
<div markdown="1">
|
||||
type: boolean
|
||||
{: .label .label-config .label-purple }
|
||||
default: false
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Overrides the behaviour to redirect logging only to the `file_path`. If set to `true` logs will be written to both
|
||||
standard output, and the defined logging location.
|
||||
|
||||
```yaml
|
||||
logging:
|
||||
keep_stdout: true
|
||||
```
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Miscellaneous
|
||||
parent: Configuration
|
||||
nav_order: 3
|
||||
nav_order: 5
|
||||
---
|
||||
|
||||
# Miscellaneous
|
||||
|
@ -93,88 +93,6 @@ key or the CA public key which signed them (don't add the private key).
|
|||
certificates_directory: /config/certs/
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
### log_level
|
||||
<div markdown="1">
|
||||
type: string
|
||||
{: .label .label-config .label-purple }
|
||||
default: info
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Defines the level of logs used by Authelia. This level can be set to `trace`, `debug` or `info`. When setting log_level
|
||||
to `trace`, you will generate a large amount of log entries and expose the `/debug/vars` and `/debug/pprof/` endpoints
|
||||
which should not be enabled in production.
|
||||
|
||||
```yaml
|
||||
log_level: debug
|
||||
```
|
||||
|
||||
### log_format
|
||||
<div markdown="1">
|
||||
type: string
|
||||
{: .label .label-config .label-purple }
|
||||
default: text
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Defines the format of the logs written by Authelia. This format can be set to `json` or `text`.
|
||||
|
||||
```yaml
|
||||
log_format: json
|
||||
```
|
||||
|
||||
#### JSON format
|
||||
```
|
||||
{"level":"info","msg":"Logging severity set to info","time":"2020-01-01T00:00:00+11:00"}
|
||||
{"level":"info","msg":"Authelia is listening for non-TLS connections on 0.0.0.0:9091","time":"2020-01-01T00:00:00+11:00"}
|
||||
```
|
||||
#### Text format
|
||||
```
|
||||
time="2020-01-01T00:00:00+11:00" level=info msg="Logging severity set to info"
|
||||
time="2020-01-01T00:00:00+11:00" level=info msg="Authelia is listening for non-TLS connections on 0.0.0.0:9091"
|
||||
```
|
||||
|
||||
### log_file_path
|
||||
<div markdown="1">
|
||||
type: string (path)
|
||||
{: .label .label-config .label-purple }
|
||||
default: ""
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Logs can be stored in a file when file path is provided. Otherwise logs are written to standard output. When setting the
|
||||
log_level to `debug` or `trace` this will generate large amount of log entries. Administrators will need to ensure that
|
||||
they rotate and/or truncate the logs over time to prevent significant long-term disk usage.
|
||||
|
||||
```yaml
|
||||
log_file_path: /config/authelia.log
|
||||
```
|
||||
|
||||
### log_keep_stdout
|
||||
<div markdown="1">
|
||||
type: boolean
|
||||
{: .label .label-config .label-purple }
|
||||
default: false
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Overrides the behaviour to redirect logging only to the `log_file_path`. If set to `true` logs will be written to both
|
||||
standard output, and the defined logging location.
|
||||
|
||||
```yaml
|
||||
log_keep_stdout: true
|
||||
```
|
||||
|
||||
## jwt_secret
|
||||
<div markdown="1">
|
||||
type: string
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Notifier
|
||||
parent: Configuration
|
||||
nav_order: 6
|
||||
nav_order: 8
|
||||
has_children: true
|
||||
---
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Time-based One-Time Password
|
||||
parent: Configuration
|
||||
nav_order: 4
|
||||
nav_order: 6
|
||||
---
|
||||
|
||||
# Time-based One-Time Password
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Regulation
|
||||
parent: Configuration
|
||||
nav_order: 5
|
||||
nav_order: 7
|
||||
---
|
||||
|
||||
# Regulation
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Secrets
|
||||
parent: Configuration
|
||||
nav_order: 6
|
||||
nav_order: 8
|
||||
---
|
||||
|
||||
# Secrets
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Server
|
||||
parent: Configuration
|
||||
nav_order: 7
|
||||
nav_order: 9
|
||||
---
|
||||
|
||||
# Server
|
||||
|
@ -16,6 +16,8 @@ server:
|
|||
read_buffer_size: 4096
|
||||
write_buffer_size: 4096
|
||||
path: ""
|
||||
enable_pprof: false
|
||||
enable_expvars: false
|
||||
```
|
||||
|
||||
## Options
|
||||
|
@ -72,6 +74,31 @@ server:
|
|||
path: authelia
|
||||
```
|
||||
|
||||
### enable_pprof
|
||||
<div markdown="1">
|
||||
type: boolean
|
||||
{: .label .label-config .label-purple }
|
||||
default: false
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Enables the go pprof endpoints.
|
||||
|
||||
### enable_expvars
|
||||
<div markdown="1">
|
||||
type: boolean
|
||||
{: .label .label-config .label-purple }
|
||||
default: false
|
||||
{: .label .label-config .label-blue }
|
||||
required: no
|
||||
{: .label .label-config .label-green }
|
||||
</div>
|
||||
|
||||
Enables the go expvars endpoints.
|
||||
|
||||
|
||||
## Additional Notes
|
||||
|
||||
### Buffer Sizes
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Session
|
||||
parent: Configuration
|
||||
nav_order: 8
|
||||
nav_order: 10
|
||||
has_children: true
|
||||
---
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Storage backends
|
||||
parent: Configuration
|
||||
nav_order: 10
|
||||
nav_order: 12
|
||||
has_children: true
|
||||
---
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
layout: default
|
||||
title: Theme
|
||||
parent: Configuration
|
||||
nav_order: 11
|
||||
nav_order: 13
|
||||
---
|
||||
|
||||
# Theme
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
# This secret can also be set using the env variables AUTHELIA_JWT_SECRET_FILE
|
||||
jwt_secret: a_very_important_secret
|
||||
default_redirection_url: https://public.example.com
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
jwt_secret: a_very_important_secret
|
||||
default_redirection_url: https://public.example.com
|
||||
totp:
|
||||
|
|
|
@ -34,17 +34,24 @@ server:
|
|||
## Must be alphanumeric chars and should not contain any slashes.
|
||||
path: ""
|
||||
|
||||
## Enables the pprof endpoint.
|
||||
enable_pprof: false
|
||||
|
||||
## Enables the expvars endpoint.
|
||||
enable_expvars: false
|
||||
|
||||
## Level of verbosity for logs: info, debug, trace.
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
## Format the logs are written as: json, text.
|
||||
# log_format: json
|
||||
# format: json
|
||||
|
||||
## File path where the logs will be written. If not set logs are written to stdout.
|
||||
# log_file_path: /config/authelia.log
|
||||
# file_path: /config/authelia.log
|
||||
|
||||
## Whether to also log to stdout when a log_file_path is defined.
|
||||
# log_keep_stdout: false
|
||||
# keep_stdout: false
|
||||
|
||||
## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be
|
||||
## set using a secret: https://www.authelia.com/docs/configuration/secrets.html
|
||||
|
|
|
@ -164,7 +164,7 @@ func TestShouldErrorParseBadConfigFile(t *testing.T) {
|
|||
|
||||
require.Len(t, errors, 1)
|
||||
|
||||
require.EqualError(t, errors[0], "Error malformed yaml: line 24: did not find expected alphabetic or numeric character")
|
||||
require.EqualError(t, errors[0], "Error malformed yaml: line 25: did not find expected alphabetic or numeric character")
|
||||
}
|
||||
|
||||
func TestShouldParseConfigFile(t *testing.T) {
|
||||
|
@ -185,7 +185,7 @@ func TestShouldParseConfigFile(t *testing.T) {
|
|||
require.Len(t, errors, 0)
|
||||
|
||||
assert.Equal(t, 9091, config.Port)
|
||||
assert.Equal(t, "debug", config.LogLevel)
|
||||
assert.Equal(t, "debug", config.Logging.Level)
|
||||
assert.Equal(t, "https://home.example.com:8080/", config.DefaultRedirectionURL)
|
||||
assert.Equal(t, "authelia.com", config.TOTP.Issuer)
|
||||
assert.Equal(t, "secret_from_env", config.JWTSecret)
|
||||
|
@ -221,7 +221,7 @@ func TestShouldParseAltConfigFile(t *testing.T) {
|
|||
require.Len(t, errors, 0)
|
||||
|
||||
assert.Equal(t, 9091, config.Port)
|
||||
assert.Equal(t, "debug", config.LogLevel)
|
||||
assert.Equal(t, "debug", config.Logging.Level)
|
||||
assert.Equal(t, "https://home.example.com:8080/", config.DefaultRedirectionURL)
|
||||
assert.Equal(t, "authelia.com", config.TOTP.Issuer)
|
||||
assert.Equal(t, "secret_from_env", config.JWTSecret)
|
||||
|
@ -253,7 +253,7 @@ func TestShouldNotParseConfigFileWithOldOrUnexpectedKeys(t *testing.T) {
|
|||
return errors[i].Error() < errors[j].Error()
|
||||
})
|
||||
assert.EqualError(t, errors[0], "config key not expected: loggy_file")
|
||||
assert.EqualError(t, errors[1], "invalid configuration key 'logs_level' was replaced by 'log_level'")
|
||||
assert.EqualError(t, errors[1], "invalid configuration key 'logs_level' was replaced by 'logging.level'")
|
||||
}
|
||||
|
||||
func TestShouldValidateConfigurationTemplate(t *testing.T) {
|
||||
|
|
|
@ -8,13 +8,16 @@ type Configuration struct {
|
|||
TLSCert string `mapstructure:"tls_cert"`
|
||||
TLSKey string `mapstructure:"tls_key"`
|
||||
CertificatesDirectory string `mapstructure:"certificates_directory"`
|
||||
LogLevel string `mapstructure:"log_level"`
|
||||
LogFormat string `mapstructure:"log_format"`
|
||||
LogFilePath string `mapstructure:"log_file_path"`
|
||||
LogKeepStdout bool `mapstructure:"log_keep_stdout"`
|
||||
JWTSecret string `mapstructure:"jwt_secret"`
|
||||
DefaultRedirectionURL string `mapstructure:"default_redirection_url"`
|
||||
|
||||
// TODO: DEPRECATED START. Remove in 4.33.0.
|
||||
LogLevel string `mapstructure:"log_level"`
|
||||
LogFormat string `mapstructure:"log_format"`
|
||||
LogFilePath string `mapstructure:"log_file_path"`
|
||||
// TODO: DEPRECATED END. Remove in 4.33.0.
|
||||
|
||||
Logging LoggingConfiguration `mapstructure:"logging"`
|
||||
IdentityProviders IdentityProvidersConfiguration `mapstructure:"identity_providers"`
|
||||
AuthenticationBackend AuthenticationBackendConfiguration `mapstructure:"authentication_backend"`
|
||||
Session SessionConfiguration `mapstructure:"session"`
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package schema
|
||||
|
||||
// LoggingConfiguration represents the logging configuration.
|
||||
type LoggingConfiguration struct {
|
||||
Level string `mapstructure:"level"`
|
||||
Format string `mapstructure:"format"`
|
||||
FilePath string `mapstructure:"file_path"`
|
||||
KeepStdout bool `mapstructure:"keep_stdout"`
|
||||
}
|
||||
|
||||
// DefaultLoggingConfiguration is the default logging configuration.
|
||||
var DefaultLoggingConfiguration = LoggingConfiguration{
|
||||
Level: "info",
|
||||
Format: "text",
|
||||
}
|
|
@ -5,6 +5,8 @@ type ServerConfiguration struct {
|
|||
Path string `mapstructure:"path"`
|
||||
ReadBufferSize int `mapstructure:"read_buffer_size"`
|
||||
WriteBufferSize int `mapstructure:"write_buffer_size"`
|
||||
EnablePprof bool `mapstructure:"enable_endpoint_pprof"`
|
||||
EnableExpvars bool `mapstructure:"enable_endpoint_expvars"`
|
||||
}
|
||||
|
||||
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
host: 127.0.0.1
|
||||
port: 9091
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
totp:
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
host: 127.0.0.1
|
||||
port: 9091
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
totp:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
---
|
||||
host: 0.0.0.0
|
||||
port: 9091
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: RUtG9TnbXrOl1XLLmDgySw1DGgx9QcrtepIf1uDDBlBVKFZxkVBruYKBi32PvaU
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ host: 127.0.0.1
|
|||
port: 9091
|
||||
jwt_secret: secret_from_config
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
totp:
|
||||
|
|
|
@ -50,7 +50,11 @@ func IsNetworkValid(network string) (isValid bool) {
|
|||
}
|
||||
|
||||
// ValidateAccessControl validates access control configuration.
|
||||
func ValidateAccessControl(configuration schema.AccessControlConfiguration, validator *schema.StructValidator) {
|
||||
func ValidateAccessControl(configuration *schema.AccessControlConfiguration, validator *schema.StructValidator) {
|
||||
if configuration.DefaultPolicy == "" {
|
||||
configuration.DefaultPolicy = denyPolicy
|
||||
}
|
||||
|
||||
if !IsPolicyValid(configuration.DefaultPolicy) {
|
||||
validator.Push(fmt.Errorf("'default_policy' must either be 'deny', 'two_factor', 'one_factor' or 'bypass'"))
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ func (suite *AccessControl) SetupTest() {
|
|||
}
|
||||
|
||||
func (suite *AccessControl) TestShouldValidateCompleteConfiguration() {
|
||||
ValidateAccessControl(suite.configuration, suite.validator)
|
||||
ValidateAccessControl(&suite.configuration, suite.validator)
|
||||
|
||||
suite.Assert().False(suite.validator.HasWarnings())
|
||||
suite.Assert().False(suite.validator.HasErrors())
|
||||
|
@ -33,7 +33,7 @@ func (suite *AccessControl) TestShouldValidateCompleteConfiguration() {
|
|||
func (suite *AccessControl) TestShouldRaiseErrorInvalidDefaultPolicy() {
|
||||
suite.configuration.DefaultPolicy = testInvalidPolicy
|
||||
|
||||
ValidateAccessControl(suite.configuration, suite.validator)
|
||||
ValidateAccessControl(&suite.configuration, suite.validator)
|
||||
|
||||
suite.Assert().False(suite.validator.HasWarnings())
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
@ -49,7 +49,7 @@ func (suite *AccessControl) TestShouldRaiseErrorInvalidNetworkGroupNetwork() {
|
|||
},
|
||||
}
|
||||
|
||||
ValidateAccessControl(suite.configuration, suite.validator)
|
||||
ValidateAccessControl(&suite.configuration, suite.validator)
|
||||
|
||||
suite.Assert().False(suite.validator.HasWarnings())
|
||||
suite.Require().Len(suite.validator.Errors(), 1)
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
)
|
||||
|
||||
var defaultPort = 9091
|
||||
var defaultLogLevel = "info"
|
||||
|
||||
// ValidateConfiguration and adapt the configuration read from file.
|
||||
//nolint:gocyclo // This function is likely to always have lots of if/else statements, as long as we keep the flow clean it should be understandable.
|
||||
|
@ -37,10 +36,6 @@ func ValidateConfiguration(configuration *schema.Configuration, validator *schem
|
|||
}
|
||||
}
|
||||
|
||||
if configuration.LogLevel == "" {
|
||||
configuration.LogLevel = defaultLogLevel
|
||||
}
|
||||
|
||||
if configuration.JWTSecret == "" {
|
||||
validator.Push(fmt.Errorf("Provide a JWT secret using \"jwt_secret\" key"))
|
||||
}
|
||||
|
@ -52,25 +47,19 @@ func ValidateConfiguration(configuration *schema.Configuration, validator *schem
|
|||
}
|
||||
}
|
||||
|
||||
if configuration.Theme == "" {
|
||||
configuration.Theme = "light"
|
||||
}
|
||||
|
||||
ValidateTheme(configuration, validator)
|
||||
|
||||
if configuration.TOTP == nil {
|
||||
configuration.TOTP = &schema.DefaultTOTPConfiguration
|
||||
}
|
||||
|
||||
ValidateLogging(configuration, validator)
|
||||
|
||||
ValidateTOTP(configuration.TOTP, validator)
|
||||
|
||||
ValidateAuthenticationBackend(&configuration.AuthenticationBackend, validator)
|
||||
|
||||
if configuration.AccessControl.DefaultPolicy == "" {
|
||||
configuration.AccessControl.DefaultPolicy = denyPolicy
|
||||
}
|
||||
|
||||
ValidateAccessControl(configuration.AccessControl, validator)
|
||||
ValidateAccessControl(&configuration.AccessControl, validator)
|
||||
|
||||
ValidateRules(configuration.AccessControl, validator)
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ func newDefaultConfig() schema.Configuration {
|
|||
config := schema.Configuration{}
|
||||
config.Host = "127.0.0.1"
|
||||
config.Port = 9090
|
||||
config.LogLevel = "info"
|
||||
config.LogFormat = "text"
|
||||
config.Logging.Level = "info"
|
||||
config.Logging.Format = "text"
|
||||
config.JWTSecret = testJWTSecret
|
||||
config.AuthenticationBackend.File = &schema.FileAuthenticationBackendConfiguration{
|
||||
Path: "/a/path",
|
||||
|
@ -48,7 +48,7 @@ func TestShouldNotUpdateConfig(t *testing.T) {
|
|||
|
||||
require.Len(t, validator.Errors(), 0)
|
||||
assert.Equal(t, 9090, config.Port)
|
||||
assert.Equal(t, "info", config.LogLevel)
|
||||
assert.Equal(t, "info", config.Logging.Level)
|
||||
}
|
||||
|
||||
func TestShouldValidateAndUpdatePort(t *testing.T) {
|
||||
|
@ -73,17 +73,6 @@ func TestShouldValidateAndUpdateHost(t *testing.T) {
|
|||
assert.Equal(t, "0.0.0.0", config.Host)
|
||||
}
|
||||
|
||||
func TestShouldValidateAndUpdateLogsLevel(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultConfig()
|
||||
config.LogLevel = ""
|
||||
|
||||
ValidateConfiguration(&config, validator)
|
||||
|
||||
require.Len(t, validator.Errors(), 0)
|
||||
assert.Equal(t, "info", config.LogLevel)
|
||||
}
|
||||
|
||||
func TestShouldEnsureNotifierConfigIsProvided(t *testing.T) {
|
||||
validator := schema.NewStructValidator()
|
||||
config := newDefaultConfig()
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
package validator
|
||||
|
||||
const (
|
||||
errFmtDeprecatedConfigurationKey = "[DEPRECATED] The %s configuration option is deprecated and will be " +
|
||||
"removed in %s, please use %s instead"
|
||||
errFmtReplacedConfigurationKey = "invalid configuration key '%s' was replaced by '%s'"
|
||||
|
||||
errFmtLoggingLevelInvalid = "the log level '%s' is invalid, must be one of: %s"
|
||||
|
||||
errFmtSessionSecretRedisProvider = "The session secret must be set when using the %s session provider"
|
||||
errFmtSessionRedisPortRange = "The port must be between 1 and 65535 for the %s session provider"
|
||||
errFmtSessionRedisHostRequired = "The host must be provided when using the %s session provider"
|
||||
errFmtSessionRedisHostOrNodesRequired = "Either the host or a node must be provided when using the %s session provider"
|
||||
errFmtReplacedConfigurationKey = "invalid configuration key '%s' was replaced by '%s'"
|
||||
|
||||
errOAuthOIDCServerClientRedirectURIFmt = "OIDC Server Client redirect URI %s has an invalid scheme %s, should be http or https"
|
||||
errOAuthOIDCServerClientRedirectURICantBeParsedFmt = "OIDC Client with ID '%s' has an invalid redirect URI '%s' could not be parsed: %v"
|
||||
|
@ -43,6 +48,7 @@ const (
|
|||
"https://www.authelia.com/docs/configuration/access-control.html#combining-subjects-and-the-bypass-policy"
|
||||
)
|
||||
|
||||
var validLoggingLevels = []string{"trace", "debug", "info", "warn", "error"}
|
||||
var validRequestMethods = []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "TRACE", "CONNECT", "OPTIONS"}
|
||||
|
||||
// SecretNames contains a map of secret names.
|
||||
|
@ -66,19 +72,30 @@ var validKeys = []string{
|
|||
// Root Keys.
|
||||
"host",
|
||||
"port",
|
||||
"log_level",
|
||||
"log_format",
|
||||
"log_file_path",
|
||||
"default_redirection_url",
|
||||
"theme",
|
||||
"tls_key",
|
||||
"tls_cert",
|
||||
"certificates_directory",
|
||||
|
||||
// Logging keys.
|
||||
"logging.level",
|
||||
"logging.format",
|
||||
"logging.file_path",
|
||||
"logging.keep_stdout",
|
||||
|
||||
// TODO: DEPRECATED START. Remove in 4.33.0.
|
||||
"log_level",
|
||||
"log_format",
|
||||
"log_file_path",
|
||||
// TODO: DEPRECATED END. Remove in 4.33.0.
|
||||
|
||||
// Server Keys.
|
||||
"server.read_buffer_size",
|
||||
"server.write_buffer_size",
|
||||
"server.path",
|
||||
"server.enable_pprof",
|
||||
"server.enable_expvars",
|
||||
|
||||
// TOTP Keys.
|
||||
"totp.issuer",
|
||||
|
@ -200,8 +217,8 @@ var replacedKeys = map[string]string{
|
|||
"authentication_backend.ldap.skip_verify": "authentication_backend.ldap.tls.skip_verify",
|
||||
"authentication_backend.ldap.minimum_tls_version": "authentication_backend.ldap.tls.minimum_version",
|
||||
"notifier.smtp.disable_verify_cert": "notifier.smtp.tls.skip_verify",
|
||||
"logs_file_path": "log_file",
|
||||
"logs_level": "log_level",
|
||||
"logs_file_path": "logging.file_path",
|
||||
"logs_level": "logging.level",
|
||||
}
|
||||
|
||||
var specificErrorKeys = map[string]string{
|
||||
|
|
|
@ -106,8 +106,8 @@ func TestReplacedErrors(t *testing.T) {
|
|||
assert.EqualError(t, errs[0], fmt.Sprintf(errFmtReplacedConfigurationKey, "authentication_backend.ldap.skip_verify", "authentication_backend.ldap.tls.skip_verify"))
|
||||
assert.EqualError(t, errs[1], fmt.Sprintf(errFmtReplacedConfigurationKey, "authentication_backend.ldap.minimum_tls_version", "authentication_backend.ldap.tls.minimum_version"))
|
||||
assert.EqualError(t, errs[2], fmt.Sprintf(errFmtReplacedConfigurationKey, "notifier.smtp.disable_verify_cert", "notifier.smtp.tls.skip_verify"))
|
||||
assert.EqualError(t, errs[3], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_file_path", "log_file"))
|
||||
assert.EqualError(t, errs[4], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_level", "log_level"))
|
||||
assert.EqualError(t, errs[3], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_file_path", "logging.file_path"))
|
||||
assert.EqualError(t, errs[4], fmt.Sprintf(errFmtReplacedConfigurationKey, "logs_level", "logging.level"))
|
||||
}
|
||||
|
||||
func TestSecretKeysDontRaiseErrors(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/authelia/authelia/internal/configuration/schema"
|
||||
"github.com/authelia/authelia/internal/utils"
|
||||
)
|
||||
|
||||
// ValidateLogging validates the logging configuration.
|
||||
func ValidateLogging(configuration *schema.Configuration, validator *schema.StructValidator) {
|
||||
applyDeprecatedLoggingConfiguration(configuration, validator) // TODO: DEPRECATED LINE. Remove in 4.33.0.
|
||||
|
||||
if configuration.Logging.Level == "" {
|
||||
configuration.Logging.Level = schema.DefaultLoggingConfiguration.Level
|
||||
}
|
||||
|
||||
if configuration.Logging.Format == "" {
|
||||
configuration.Logging.Format = schema.DefaultLoggingConfiguration.Format
|
||||
}
|
||||
|
||||
if !utils.IsStringInSlice(configuration.Logging.Level, validLoggingLevels) {
|
||||
validator.Push(fmt.Errorf(errFmtLoggingLevelInvalid, configuration.Logging.Level, strings.Join(validLoggingLevels, ", ")))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: DEPRECATED FUNCTION. Remove in 4.33.0.
|
||||
func applyDeprecatedLoggingConfiguration(configuration *schema.Configuration, validator *schema.StructValidator) {
|
||||
if configuration.LogLevel != "" {
|
||||
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "log_level", "4.33.0", "logging.level"))
|
||||
|
||||
if configuration.Logging.Level == "" {
|
||||
configuration.Logging.Level = configuration.LogLevel
|
||||
}
|
||||
}
|
||||
|
||||
if configuration.LogFormat != "" {
|
||||
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "log_format", "4.33.0", "logging.format"))
|
||||
|
||||
if configuration.Logging.Format == "" {
|
||||
configuration.Logging.Format = configuration.LogFormat
|
||||
}
|
||||
}
|
||||
|
||||
if configuration.LogFilePath != "" {
|
||||
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "log_file_path", "4.33.0", "logging.file_path"))
|
||||
|
||||
if configuration.Logging.FilePath == "" {
|
||||
configuration.Logging.FilePath = configuration.LogFilePath
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package validator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/authelia/authelia/internal/configuration/schema"
|
||||
)
|
||||
|
||||
func TestShouldSetDefaultLoggingValues(t *testing.T) {
|
||||
config := &schema.Configuration{}
|
||||
|
||||
validator := schema.NewStructValidator()
|
||||
|
||||
ValidateLogging(config, validator)
|
||||
|
||||
assert.Len(t, validator.Warnings(), 0)
|
||||
assert.Len(t, validator.Errors(), 0)
|
||||
|
||||
require.NotNil(t, config.Logging.KeepStdout)
|
||||
|
||||
assert.Equal(t, "", config.LogLevel)
|
||||
assert.Equal(t, "", config.LogFormat)
|
||||
assert.Equal(t, "", config.LogFilePath)
|
||||
|
||||
assert.Equal(t, "info", config.Logging.Level)
|
||||
assert.Equal(t, "text", config.Logging.Format)
|
||||
assert.Equal(t, "", config.Logging.FilePath)
|
||||
}
|
||||
|
||||
func TestShouldRaiseErrorOnInvalidLoggingLevel(t *testing.T) {
|
||||
config := &schema.Configuration{
|
||||
Logging: schema.LoggingConfiguration{
|
||||
Level: "TRACE",
|
||||
},
|
||||
}
|
||||
|
||||
validator := schema.NewStructValidator()
|
||||
|
||||
ValidateLogging(config, validator)
|
||||
|
||||
assert.Len(t, validator.Warnings(), 0)
|
||||
require.Len(t, validator.Errors(), 1)
|
||||
|
||||
assert.EqualError(t, validator.Errors()[0], "the log level 'TRACE' is invalid, must be one of: trace, debug, info, warn, error")
|
||||
}
|
||||
|
||||
// TODO: DEPRECATED TEST. Remove in 4.33.0.
|
||||
func TestShouldMigrateDeprecatedLoggingConfig(t *testing.T) {
|
||||
config := &schema.Configuration{
|
||||
LogLevel: "trace",
|
||||
LogFormat: "json",
|
||||
LogFilePath: "/a/b/c",
|
||||
}
|
||||
|
||||
validator := schema.NewStructValidator()
|
||||
|
||||
ValidateLogging(config, validator)
|
||||
|
||||
assert.Len(t, validator.Errors(), 0)
|
||||
require.Len(t, validator.Warnings(), 3)
|
||||
|
||||
require.NotNil(t, config.Logging.KeepStdout)
|
||||
|
||||
assert.Equal(t, "trace", config.LogLevel)
|
||||
assert.Equal(t, "json", config.LogFormat)
|
||||
assert.Equal(t, "/a/b/c", config.LogFilePath)
|
||||
|
||||
assert.Equal(t, "trace", config.Logging.Level)
|
||||
assert.Equal(t, "json", config.Logging.Format)
|
||||
assert.Equal(t, "/a/b/c", config.Logging.FilePath)
|
||||
|
||||
assert.EqualError(t, validator.Warnings()[0], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_level", "4.33.0", "logging.level"))
|
||||
assert.EqualError(t, validator.Warnings()[1], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_format", "4.33.0", "logging.format"))
|
||||
assert.EqualError(t, validator.Warnings()[2], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_file_path", "4.33.0", "logging.file_path"))
|
||||
}
|
||||
|
||||
func TestShouldRaiseErrorsAndNotOverwriteConfigurationWhenUsingDeprecatedLoggingConfig(t *testing.T) {
|
||||
config := &schema.Configuration{
|
||||
Logging: schema.LoggingConfiguration{
|
||||
Level: "info",
|
||||
Format: "text",
|
||||
FilePath: "/x/y/z",
|
||||
KeepStdout: true,
|
||||
},
|
||||
LogLevel: "debug",
|
||||
LogFormat: "json",
|
||||
LogFilePath: "/a/b/c",
|
||||
}
|
||||
|
||||
validator := schema.NewStructValidator()
|
||||
|
||||
ValidateLogging(config, validator)
|
||||
|
||||
require.NotNil(t, config.Logging.KeepStdout)
|
||||
|
||||
assert.Equal(t, "info", config.Logging.Level)
|
||||
assert.Equal(t, "text", config.Logging.Format)
|
||||
assert.True(t, config.Logging.KeepStdout)
|
||||
assert.Equal(t, "/x/y/z", config.Logging.FilePath)
|
||||
|
||||
assert.Len(t, validator.Errors(), 0)
|
||||
require.Len(t, validator.Warnings(), 3)
|
||||
|
||||
assert.EqualError(t, validator.Warnings()[0], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_level", "4.33.0", "logging.level"))
|
||||
assert.EqualError(t, validator.Warnings()[1], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_format", "4.33.0", "logging.format"))
|
||||
assert.EqualError(t, validator.Warnings()[2], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "log_file_path", "4.33.0", "logging.file_path"))
|
||||
}
|
|
@ -9,6 +9,10 @@ import (
|
|||
|
||||
// ValidateTheme validates and update Theme configuration.
|
||||
func ValidateTheme(configuration *schema.Configuration, validator *schema.StructValidator) {
|
||||
if configuration.Theme == "" {
|
||||
configuration.Theme = "light"
|
||||
}
|
||||
|
||||
validThemes := regexp.MustCompile("light|dark|grey")
|
||||
if !validThemes.MatchString(configuration.Theme) {
|
||||
validator.Push(fmt.Errorf("Theme: %s is not valid, valid themes are: \"light\", \"dark\" or \"grey\"", configuration.Theme))
|
||||
|
|
|
@ -339,7 +339,7 @@ func verifySessionHasUpToDateProfile(ctx *middlewares.AutheliaCtx, targetURL *ur
|
|||
}
|
||||
} else {
|
||||
ctx.Logger.Debugf("Updated profile detected for %s.", userSession.Username)
|
||||
if ctx.Configuration.LogLevel == "trace" {
|
||||
if ctx.Configuration.Logging.Level == "trace" {
|
||||
generateVerifySessionHasUpToDateProfileTraceLogs(ctx, userSession, details)
|
||||
}
|
||||
userSession.Emails = details.Emails
|
||||
|
|
|
@ -127,9 +127,11 @@ func registerRoutes(configuration schema.Configuration, providers middlewares.Pr
|
|||
middlewares.RequireFirstFactor(handlers.SecondFactorDuoPost(duoAPI))))
|
||||
}
|
||||
|
||||
// If trace is set, enable pprofhandler and expvarhandler.
|
||||
if configuration.LogLevel == "trace" {
|
||||
if configuration.Server.EnablePprof {
|
||||
r.GET("/debug/pprof/{name?}", pprofhandler.PprofHandler)
|
||||
}
|
||||
|
||||
if configuration.Server.EnableExpvars {
|
||||
r.GET("/debug/vars", expvarhandler.ExpvarHandler)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ tls_key: /config/ssl/key.pem
|
|||
|
||||
theme: grey
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: trace
|
||||
logging:
|
||||
level: trace
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ tls_key: /config/ssl/key.pem
|
|||
|
||||
theme: dark
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_password
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ tls_key: /config/ssl/key.pem
|
|||
server:
|
||||
path: auth
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080/
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
authentication_backend:
|
||||
file:
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 9091
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
jwt_secret: unsecure_secret
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ port: 443
|
|||
tls_cert: /config/ssl/cert.pem
|
||||
tls_key: /config/ssl/key.pem
|
||||
|
||||
log_level: debug
|
||||
logging:
|
||||
level: debug
|
||||
|
||||
default_redirection_url: https://home.example.com:8080
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ func IsStringAlphaNumeric(input string) bool {
|
|||
}
|
||||
|
||||
// IsStringInSlice checks if a single string is in a slice of strings.
|
||||
func IsStringInSlice(a string, slice []string) (inSlice bool) {
|
||||
for _, b := range slice {
|
||||
if b == a {
|
||||
func IsStringInSlice(needle string, haystack []string) (inSlice bool) {
|
||||
for _, b := range haystack {
|
||||
if b == needle {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ func IsStringInSlice(a string, slice []string) (inSlice bool) {
|
|||
}
|
||||
|
||||
// IsStringInSliceFold checks if a single string is in a slice of strings but uses strings.EqualFold to compare them.
|
||||
func IsStringInSliceFold(a string, slice []string) (inSlice bool) {
|
||||
for _, b := range slice {
|
||||
if strings.EqualFold(b, a) {
|
||||
func IsStringInSliceFold(needle string, haystack []string) (inSlice bool) {
|
||||
for _, b := range haystack {
|
||||
if strings.EqualFold(b, needle) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ func IsStringInSliceFold(a string, slice []string) (inSlice bool) {
|
|||
}
|
||||
|
||||
// IsStringInSliceContains checks if a single string is in an array of strings.
|
||||
func IsStringInSliceContains(a string, list []string) (inSlice bool) {
|
||||
for _, b := range list {
|
||||
if strings.Contains(a, b) {
|
||||
func IsStringInSliceContains(needle string, haystack []string) (inSlice bool) {
|
||||
for _, b := range haystack {
|
||||
if strings.Contains(needle, b) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue