feat(configuration): replace several configuration options (#2209)

This change adjusts several global options moving them into the server block. It additionally notes other breaking changes in the configuration.

BREAKING CHANGE: Several configuration options have been changed and moved into other sections. Migration instructions are documented here: https://authelia.com/docs/configuration/migration.html#4.30.0
pull/2225/head
James Elliott 2021-08-02 21:55:30 +10:00 committed by GitHub
parent ac17841721
commit 158783a9d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 682 additions and 417 deletions

View File

@ -4,14 +4,6 @@
# Authelia Configuration #
###############################################################################
## The host and port to listen on.
host: 0.0.0.0
port: 9091
## The TLS key and cert used with Authelia.
# tls_key: /config/ssl/key.pem
# tls_cert: /config/ssl/cert.pem
## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
## the system certificates store.
## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
@ -20,10 +12,39 @@ port: 9091
## The theme to display: light, dark, grey, auto.
theme: light
## 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
jwt_secret: a_very_important_secret
## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
default_redirection_url: https://home.example.com/
##
## Server Configuration
##
server:
## The address to listen on.
host: 0.0.0.0
## The port to listen on.
port: 9091
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls:
## The path to the DER base64/PEM format private key.
key: ""
# key: /config/ssl/key.pem
## The path to the DER base64/PEM format public certificate.
certificate: ""
# certificate: /config/ssl/cert.pem
## Buffers usually should be configured to be the same value.
## Explanation at https://www.authelia.com/docs/configuration/server.html
## Read buffer size adjusts the server's max incoming request size in bytes.
@ -54,19 +75,6 @@ log:
## Whether to also log to stdout when a log_file_path is defined.
# 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
jwt_secret: a_very_important_secret
## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
default_redirection_url: https://home.example.com/
##
## TOTP Configuration
##

View File

@ -1,8 +1,8 @@
---
layout: default
title: Authentication backends
title: Authentication Backends
parent: Configuration
nav_order: 1
nav_order: 2
has_children: true
---

View File

@ -2,7 +2,7 @@
layout: default
title: Duo Push Notifications
parent: Configuration
nav_order: 2
nav_order: 3
---
# Duo Push Notifications

View File

@ -2,7 +2,7 @@
layout: default
title: Identity Providers
parent: Configuration
nav_order: 3
nav_order: 4
has_children: true
---

View File

@ -2,7 +2,7 @@
layout: default
title: Logging
parent: Configuration
nav_order: 4
nav_order: 5
---
# Logging

View File

@ -0,0 +1,70 @@
---
layout: default
title: Migration
parent: Configuration
nav_order: 6
---
This section documents changes in the configuration which may require manual migration by the administrator. Typically
this only occurs when a configuration key is renamed or moved to a more appropriate location.
## Format
The migrations are formatted in a table with the old key and the new key. Periods indicate a different section which can
be represented in YAML as a dictionary i.e. it's indented.
In our table `server.host` with a value of `0.0.0.0` is represented in YAML like this:
```yaml
server:
host: 0.0.0.0
```
## Policy
Our deprecation policy for configuration keys is 3 minor versions. For example if a configuration option is deprecated
in version 4.30.0, it will remain as a warning for 4.30.x, 4.31.x, and 4.32.x; then it will become a fatal error in
4.33.0+.
## Migrations
### 4.30.0
The following changes occurred in 4.30.0:
|Previous Key|New Key |
|:----------:|:--------------------:|
|host |server.host |
|port |server.port |
|tls_key |server.tls.key |
|tls_cert |server.tls.certificate|
|log_level |log.level |
|log_file |log.file |
|log_format |log.format |
### 4.25.0
The following changes occurred in 4.25.0:
|Previous Key |New Key |
|:---------------------------------------------:|:---------------------------------------------:|
|authentication_backend.ldap.tls.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 |
|notifier.smtp.trusted_cert |certificates_directory |
_**Please Note:** `certificates_directory` is not a direct replacement for the `notifier.smtp.trusted_cert`, instead
of being the path to a specific file it is a path to a directory containing certificates trusted by Authelia. This
affects other services like LDAP as well._
### 4.7.0
The following changes occurred in 4.7.0:
|Previous Key|New Key |
|:----------:|:-------:|
|logs_level |log_level|
|logs_file |log_file |
_**Please Note:** The new keys also changed in [4.30.0](#4.30.0) so you will need to update them to the new values if you
are using [4.30.0](#4.30.0) or newer instead of the new keys listed here._

View File

@ -2,85 +2,12 @@
layout: default
title: Miscellaneous
parent: Configuration
nav_order: 5
nav_order: 7
---
# Miscellaneous
Here are the main customizable options in Authelia.
## Host & Port
```yaml
host: 0.0.0.0
port: 9091
```
### host
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: 0.0.0.0
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Defines the address to listen on. See also [port](#port). Should typically be `0.0.0.0` or `127.0.0.1`, the former for
containerized environments and the later for daemonized environments like init.d and systemd.
Note: If utilising an IPv6 literal address it must be enclosed by square brackets and quoted:
```yaml
host: "[fd00:1111:2222:3333::1]"
```
### port
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 9091
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Defines the port to listen on. See also [host](#host).
## TLS
Authelia's port typically listens for plain unencrypted connections. This is by design as most environments allow to
security on lower areas of the OSI model. However it required, if you specify both of the tls options the port will
listen for TLS connections.
```yaml
tls_key: /config/ssl/key.pem
tls_cert: /config/ssl/cert.pem
```
### tls_key
<div markdown="1">
type: string (path)
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: situational
{: .label .label-config .label-yellow }
</div>
The path to the private key for TLS connections. Must be in DER base64/PEM format.
### tls_cert
<div markdown="1">
type: string (path)
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: situational
{: .label .label-config .label-yellow }
</div>
The path to the public certificate for TLS connections. Must be in DER base64/PEM format.
Here are the main customizable options in Authelia that don't fit into their own sections.
## certificates_directory

View File

@ -2,7 +2,7 @@
layout: default
title: Time-based One-Time Password
parent: Configuration
nav_order: 6
nav_order: 15
---
# Time-based One-Time Password

View File

@ -2,7 +2,7 @@
layout: default
title: Regulation
parent: Configuration
nav_order: 7
nav_order: 9
---
# Regulation

View File

@ -2,7 +2,7 @@
layout: default
title: Secrets
parent: Configuration
nav_order: 8
nav_order: 10
---
# Secrets

View File

@ -2,7 +2,7 @@
layout: default
title: Server
parent: Configuration
nav_order: 9
nav_order: 11
---
# Server
@ -13,15 +13,51 @@ The server section configures and tunes the http server module Authelia uses.
```yaml
server:
host: 0.0.0.0
port: 9091
read_buffer_size: 4096
write_buffer_size: 4096
path: ""
enable_pprof: false
enable_expvars: false
tls:
key: ""
certificate: ""
```
## Options
## host
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: 0.0.0.0
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Defines the address to listen on. See also [port](#port). Should typically be `0.0.0.0` or `127.0.0.1`, the former for
containerized environments and the later for daemonized environments like init.d and systemd.
Note: If utilising an IPv6 literal address it must be enclosed by square brackets and quoted:
```yaml
host: "[fd00:1111:2222:3333::1]"
```
### port
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 9091
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Defines the port to listen on. See also [host](#host).
### read_buffer_size
<div markdown="1">
type: integer
@ -98,6 +134,35 @@ required: no
Enables the go expvars endpoints.
### tls
Authelia typically listens for plain unencrypted connections. This is by design as most environments allow to
security on lower areas of the OSI model. However it required, if you specify both the [tls key](#key) and
[tls certificate](#certificate) options, Authelia will listen for TLS connections.
#### key
<div markdown="1">
type: string (path)
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: situational
{: .label .label-config .label-yellow }
</div>
The path to the private key for TLS connections. Must be in DER base64/PEM format.
#### certificate
<div markdown="1">
type: string (path)
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: situational
{: .label .label-config .label-yellow }
</div>
The path to the public certificate for TLS connections. Must be in DER base64/PEM format.
## Additional Notes

View File

@ -2,7 +2,7 @@
layout: default
title: Session
parent: Configuration
nav_order: 10
nav_order: 12
has_children: true
---

View File

@ -1,8 +1,8 @@
---
layout: default
title: Storage backends
title: Storage Backends
parent: Configuration
nav_order: 12
nav_order: 13
has_children: true
---

View File

@ -2,7 +2,7 @@
layout: default
title: Theme
parent: Configuration
nav_order: 13
nav_order: 14
---
# Theme

View File

@ -3,13 +3,17 @@
# Authelia configuration #
###############################################################
jwt_secret: a_very_important_secret
default_redirection_url: https://public.example.com
server:
host: 0.0.0.0
port: 9091
log:
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
totp:
issuer: authelia.com

View File

@ -3,12 +3,16 @@
# Authelia configuration #
###############################################################
host: 0.0.0.0
port: 9091
log:
level: debug
jwt_secret: a_very_important_secret
default_redirection_url: https://public.example.com
server:
host: 0.0.0.0
port: 9091
log:
level: debug
totp:
issuer: authelia.com

View File

@ -4,14 +4,6 @@
# Authelia Configuration #
###############################################################################
## The host and port to listen on.
host: 0.0.0.0
port: 9091
## The TLS key and cert used with Authelia.
# tls_key: /config/ssl/key.pem
# tls_cert: /config/ssl/cert.pem
## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
## the system certificates store.
## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
@ -20,10 +12,39 @@ port: 9091
## The theme to display: light, dark, grey, auto.
theme: light
## 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
jwt_secret: a_very_important_secret
## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
default_redirection_url: https://home.example.com/
##
## Server Configuration
##
server:
## The address to listen on.
host: 0.0.0.0
## The port to listen on.
port: 9091
## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour.
tls:
## The path to the DER base64/PEM format private key.
key: ""
# key: /config/ssl/key.pem
## The path to the DER base64/PEM format public certificate.
certificate: ""
# certificate: /config/ssl/cert.pem
## Buffers usually should be configured to be the same value.
## Explanation at https://www.authelia.com/docs/configuration/server.html
## Read buffer size adjusts the server's max incoming request size in bytes.
@ -54,19 +75,6 @@ log:
## Whether to also log to stdout when a log_file_path is defined.
# 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
jwt_secret: a_very_important_secret
## Default redirection URL
##
## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end
## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use
## in such a case.
##
## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
default_redirection_url: https://home.example.com/
##
## TOTP Configuration
##

View File

@ -164,7 +164,7 @@ func TestShouldErrorParseBadConfigFile(t *testing.T) {
require.Len(t, errors, 1)
require.EqualError(t, errors[0], "Error malformed yaml: line 26: did not find expected alphabetic or numeric character")
require.EqualError(t, errors[0], "Error malformed yaml: line 27: did not find expected alphabetic or numeric character")
}
func TestShouldParseConfigFile(t *testing.T) {
@ -184,7 +184,7 @@ func TestShouldParseConfigFile(t *testing.T) {
require.Len(t, errors, 0)
assert.Equal(t, 9091, config.Port)
assert.Equal(t, 9091, config.Server.Port)
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)
@ -220,7 +220,7 @@ func TestShouldParseAltConfigFile(t *testing.T) {
config, errors := Read("./test_resources/config_alt.yml")
require.Len(t, errors, 0)
assert.Equal(t, 9091, config.Port)
assert.Equal(t, 9091, config.Server.Port)
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)

View File

@ -2,20 +2,18 @@ package schema
// Configuration object extracted from YAML configuration file.
type Configuration struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Theme string `mapstructure:"theme"`
TLSCert string `mapstructure:"tls_cert"`
TLSKey string `mapstructure:"tls_key"`
CertificatesDirectory string `mapstructure:"certificates_directory"`
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.
Host string `koanf:"host"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
Port int `koanf:"port"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
TLSCert string `koanf:"tls_cert"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
TLSKey string `koanf:"tls_key"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
LogLevel string `koanf:"log_level"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
LogFormat string `koanf:"log_format"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
LogFilePath string `koanf:"log_file_path"` // Deprecated: To be Removed. TODO: Remove in 4.33.0.
Logging LogConfiguration `mapstructure:"log"`
IdentityProviders IdentityProvidersConfiguration `mapstructure:"identity_providers"`

View File

@ -2,15 +2,27 @@ package schema
// ServerConfiguration represents the configuration of the http server.
type ServerConfiguration struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
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"`
TLS ServerTLSConfiguration `mapstructure:"tls"`
}
// ServerTLSConfiguration represents the configuration of the http servers TLS options.
type ServerTLSConfiguration struct {
Certificate string `mapstructure:"certificate"`
Key string `mapstructure:"key"`
}
// DefaultServerConfiguration represents the default values of the ServerConfiguration.
var DefaultServerConfiguration = ServerConfiguration{
Host: "0.0.0.0",
Port: 9091,
ReadBufferSize: 4096,
WriteBufferSize: 4096,
}

View File

@ -1,12 +1,13 @@
---
default_redirection_url: https://home.example.com:8080/
server:
host: 127.0.0.1
port: 9091
log:
level: debug
default_redirection_url: https://home.example.com:8080/
totp:
issuer: authelia.com

View File

@ -1,12 +1,13 @@
---
default_redirection_url: https://home.example.com:8080/
server:
host: 127.0.0.1
port: 9091
log:
level: debug
default_redirection_url: https://home.example.com:8080/
totp:
issuer: authelia.com

View File

@ -1,12 +1,14 @@
---
host: 127.0.0.1
port: 9091
loggy_file: /config/svc.log
logs_level: debug
default_redirection_url: https://home.example.com:8080/
server:
host: 127.0.0.1
port: 9091
totp:
issuer: authelia.com

View File

@ -1,14 +1,15 @@
---
jwt_secret: RUtG9TnbXrOl1XLLmDgySw1DGgx9QcrtepIf1uDDBlBVKFZxkVBruYKBi32PvaU
default_redirection_url: example.com
server:
host: 0.0.0.0
port: 9091
log:
level: debug
jwt_secret: RUtG9TnbXrOl1XLLmDgySw1DGgx9QcrtepIf1uDDBlBVKFZxkVBruYKBi32PvaU
default_redirection_url: example.com
totp:
issuer: example.com
period: 30

View File

@ -1,13 +1,15 @@
---
jwt_secret: secret_from_config
default_redirection_url: https://home.example.com:8080/
server:
host: 127.0.0.1
port: 9091
jwt_secret: secret_from_config
log:
level: debug
default_redirection_url: https://home.example.com:8080/
totp:
issuer: authelia.com

View File

@ -8,25 +8,8 @@ import (
"github.com/authelia/authelia/internal/utils"
)
var defaultPort = 9091
// 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.
func ValidateConfiguration(configuration *schema.Configuration, validator *schema.StructValidator) {
if configuration.Host == "" {
configuration.Host = "0.0.0.0"
}
if configuration.Port == 0 {
configuration.Port = defaultPort
}
if configuration.TLSKey != "" && configuration.TLSCert == "" {
validator.Push(fmt.Errorf("No TLS certificate provided, please check the \"tls_cert\" which has been configured"))
} else if configuration.TLSKey == "" && configuration.TLSCert != "" {
validator.Push(fmt.Errorf("No TLS key provided, please check the \"tls_key\" which has been configured"))
}
if configuration.CertificatesDirectory != "" {
info, err := os.Stat(configuration.CertificatesDirectory)
if err != nil {
@ -71,7 +54,7 @@ func ValidateConfiguration(configuration *schema.Configuration, validator *schem
ValidateRegulation(configuration.Regulation, validator)
ValidateServer(&configuration.Server, validator)
ValidateServer(configuration, validator)
ValidateStorage(configuration.Storage, validator)

View File

@ -12,8 +12,8 @@ import (
func newDefaultConfig() schema.Configuration {
config := schema.Configuration{}
config.Host = loopback
config.Port = 9090
config.Server.Host = loopback
config.Server.Port = 9090
config.Logging.Level = "info"
config.Logging.Format = "text"
config.JWTSecret = testJWTSecret
@ -40,39 +40,6 @@ func newDefaultConfig() schema.Configuration {
return config
}
func TestShouldNotUpdateConfig(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9090, config.Port)
assert.Equal(t, "info", config.Logging.Level)
}
func TestShouldValidateAndUpdatePort(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Port = 0
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9091, config.Port)
}
func TestShouldValidateAndUpdateHost(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Host = ""
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, "0.0.0.0", config.Host)
}
func TestShouldEnsureNotifierConfigIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
@ -107,36 +74,6 @@ func TestShouldAddDefaultAccessControl(t *testing.T) {
assert.Equal(t, "deny", config.AccessControl.DefaultPolicy)
}
func TestShouldRaiseErrorWhenTLSCertWithoutKeyIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.TLSCert = testTLSCert
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 1)
assert.EqualError(t, validator.Errors()[0], "No TLS key provided, please check the \"tls_key\" which has been configured")
}
func TestShouldRaiseErrorWhenTLSKeyWithoutCertIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.TLSKey = testTLSKey
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 1)
assert.EqualError(t, validator.Errors()[0], "No TLS certificate provided, please check the \"tls_cert\" which has been configured")
}
func TestShouldNotRaiseErrorWhenBothTLSCertificateAndKeyAreProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.TLSCert = testTLSCert
config.TLSKey = testTLSKey
ValidateConfiguration(&config, validator)
require.Len(t, validator.Errors(), 0)
}
func TestShouldRaiseErrorWithUndefinedJWTSecretKey(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()

View File

@ -103,13 +103,9 @@ var SecretNames = map[string]string{
// the secret names map and reuse it in relevant sections.
var validKeys = []string{
// Root Keys.
"host",
"port",
"default_redirection_url",
"theme",
"tls_key",
"tls_cert",
"certificates_directory",
"theme",
"default_redirection_url",
// Log keys.
"log.level",
@ -118,17 +114,25 @@ var validKeys = []string{
"log.keep_stdout",
// TODO: DEPRECATED START. Remove in 4.33.0.
"host",
"port",
"tls_key",
"tls_cert",
"log_level",
"log_format",
"log_file_path",
// TODO: DEPRECATED END. Remove in 4.33.0.
// Server Keys.
"server.host",
"server.port",
"server.read_buffer_size",
"server.write_buffer_size",
"server.path",
"server.enable_pprof",
"server.enable_expvars",
"server.tls.key",
"server.tls.certificate",
// TOTP Keys.
"totp.issuer",

View File

@ -9,30 +9,77 @@ import (
"github.com/authelia/authelia/internal/utils"
)
var defaultReadBufferSize = 4096
var defaultWriteBufferSize = 4096
// ValidateServer checks a server configuration is correct.
func ValidateServer(configuration *schema.ServerConfiguration, validator *schema.StructValidator) {
switch {
case strings.Contains(configuration.Path, "/"):
validator.Push(fmt.Errorf("server path must not contain any forward slashes"))
case !utils.IsStringAlphaNumeric(configuration.Path):
validator.Push(fmt.Errorf("server path must only be alpha numeric characters"))
case configuration.Path == "": // Don't do anything if it's blank.
default:
configuration.Path = path.Clean("/" + configuration.Path)
func ValidateServer(configuration *schema.Configuration, validator *schema.StructValidator) {
applyDeprecatedServerConfiguration(configuration, validator)
if configuration.Server.Host == "" {
configuration.Server.Host = schema.DefaultServerConfiguration.Host
}
if configuration.ReadBufferSize == 0 {
configuration.ReadBufferSize = defaultReadBufferSize
} else if configuration.ReadBufferSize < 0 {
if configuration.Server.Port == 0 {
configuration.Server.Port = schema.DefaultServerConfiguration.Port
}
if configuration.Server.TLS.Key != "" && configuration.Server.TLS.Certificate == "" {
validator.Push(fmt.Errorf("server: no TLS certificate provided to accompany the TLS key, please configure the 'server.tls.certificate' option"))
} else if configuration.Server.TLS.Key == "" && configuration.Server.TLS.Certificate != "" {
validator.Push(fmt.Errorf("server: no TLS key provided to accompany the TLS certificate, please configure the 'server.tls.key' option"))
}
switch {
case strings.Contains(configuration.Server.Path, "/"):
validator.Push(fmt.Errorf("server path must not contain any forward slashes"))
case !utils.IsStringAlphaNumeric(configuration.Server.Path):
validator.Push(fmt.Errorf("server path must only be alpha numeric characters"))
case configuration.Server.Path == "": // Don't do anything if it's blank.
default:
configuration.Server.Path = path.Clean("/" + configuration.Server.Path)
}
if configuration.Server.ReadBufferSize == 0 {
configuration.Server.ReadBufferSize = schema.DefaultServerConfiguration.ReadBufferSize
} else if configuration.Server.ReadBufferSize < 0 {
validator.Push(fmt.Errorf("server read buffer size must be above 0"))
}
if configuration.WriteBufferSize == 0 {
configuration.WriteBufferSize = defaultWriteBufferSize
} else if configuration.WriteBufferSize < 0 {
if configuration.Server.WriteBufferSize == 0 {
configuration.Server.WriteBufferSize = schema.DefaultServerConfiguration.WriteBufferSize
} else if configuration.Server.WriteBufferSize < 0 {
validator.Push(fmt.Errorf("server write buffer size must be above 0"))
}
}
func applyDeprecatedServerConfiguration(configuration *schema.Configuration, validator *schema.StructValidator) {
if configuration.Host != "" {
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "host", "4.33.0", "server.host"))
if configuration.Server.Host == "" {
configuration.Server.Host = configuration.Host
}
}
if configuration.Port != 0 {
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "port", "4.33.0", "server.port"))
if configuration.Server.Port == 0 {
configuration.Server.Port = configuration.Port
}
}
if configuration.TLSCert != "" {
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "tls_cert", "4.33.0", "server.tls_cert"))
if configuration.Server.TLS.Certificate == "" {
configuration.Server.TLS.Certificate = configuration.TLSCert
}
}
if configuration.TLSKey != "" {
validator.PushWarning(fmt.Errorf(errFmtDeprecatedConfigurationKey, "tls_key", "4.33.0", "server.tls_key"))
if configuration.Server.TLS.Key == "" {
configuration.Server.TLS.Key = configuration.TLSKey
}
}
}

View File

@ -1,6 +1,7 @@
package validator
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
@ -9,55 +10,212 @@ import (
"github.com/authelia/authelia/internal/configuration/schema"
)
func TestShouldSetDefaultServerValues(t *testing.T) {
validator := schema.NewStructValidator()
config := &schema.Configuration{}
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, schema.DefaultServerConfiguration.Host, config.Server.Host)
assert.Equal(t, schema.DefaultServerConfiguration.Port, config.Server.Port)
assert.Equal(t, schema.DefaultServerConfiguration.ReadBufferSize, config.Server.ReadBufferSize)
assert.Equal(t, schema.DefaultServerConfiguration.WriteBufferSize, config.Server.WriteBufferSize)
assert.Equal(t, schema.DefaultServerConfiguration.TLS.Key, config.Server.TLS.Key)
assert.Equal(t, schema.DefaultServerConfiguration.TLS.Certificate, config.Server.TLS.Certificate)
assert.Equal(t, schema.DefaultServerConfiguration.Path, config.Server.Path)
assert.Equal(t, schema.DefaultServerConfiguration.EnableExpvars, config.Server.EnableExpvars)
assert.Equal(t, schema.DefaultServerConfiguration.EnablePprof, config.Server.EnablePprof)
}
// TODO: DEPRECATED TEST. Remove in 4.33.0.
func TestShouldNotOverrideNewValuesWithDeprecatedValues(t *testing.T) {
validator := schema.NewStructValidator()
config := &schema.Configuration{Host: "123.0.0.1", Port: 9101, TLSKey: "/tmp/key.pem", TLSCert: "/tmp/cert.pem"}
config.Server.Host = "192.168.0.2"
config.Server.Port = 80
config.Server.TLS.Key = "/tmp/new/key.pem"
config.Server.TLS.Certificate = "/tmp/new/cert.pem"
ValidateServer(config, validator)
require.Len(t, validator.Errors(), 0)
require.Len(t, validator.Warnings(), 4)
assert.EqualError(t, validator.Warnings()[0], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "host", "4.33.0", "server.host"))
assert.EqualError(t, validator.Warnings()[1], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "port", "4.33.0", "server.port"))
assert.EqualError(t, validator.Warnings()[2], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "tls_cert", "4.33.0", "server.tls_cert"))
assert.EqualError(t, validator.Warnings()[3], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "tls_key", "4.33.0", "server.tls_key"))
assert.Equal(t, "192.168.0.2", config.Server.Host)
assert.Equal(t, 80, config.Server.Port)
assert.Equal(t, "/tmp/new/key.pem", config.Server.TLS.Key)
assert.Equal(t, "/tmp/new/cert.pem", config.Server.TLS.Certificate)
}
// TODO: DEPRECATED TEST. Remove in 4.33.0.
func TestShouldSetDeprecatedValues(t *testing.T) {
validator := schema.NewStructValidator()
config := &schema.Configuration{}
config.Host = "192.168.0.1"
config.Port = 80
config.TLSCert = "/tmp/cert.pem"
config.TLSKey = "/tmp/key.pem"
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
require.Len(t, validator.Warnings(), 4)
assert.Equal(t, "192.168.0.1", config.Server.Host)
assert.Equal(t, 80, config.Server.Port)
assert.Equal(t, "/tmp/cert.pem", config.Server.TLS.Certificate)
assert.Equal(t, "/tmp/key.pem", config.Server.TLS.Key)
assert.EqualError(t, validator.Warnings()[0], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "host", "4.33.0", "server.host"))
assert.EqualError(t, validator.Warnings()[1], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "port", "4.33.0", "server.port"))
assert.EqualError(t, validator.Warnings()[2], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "tls_cert", "4.33.0", "server.tls_cert"))
assert.EqualError(t, validator.Warnings()[3], fmt.Sprintf(errFmtDeprecatedConfigurationKey, "tls_key", "4.33.0", "server.tls_key"))
}
func TestShouldSetDefaultConfig(t *testing.T) {
validator := schema.NewStructValidator()
config := schema.ServerConfiguration{}
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, defaultReadBufferSize, config.ReadBufferSize)
assert.Equal(t, defaultWriteBufferSize, config.WriteBufferSize)
config := &schema.Configuration{}
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, schema.DefaultServerConfiguration.ReadBufferSize, config.Server.ReadBufferSize)
assert.Equal(t, schema.DefaultServerConfiguration.WriteBufferSize, config.Server.WriteBufferSize)
}
func TestShouldParsePathCorrectly(t *testing.T) {
validator := schema.NewStructValidator()
config := schema.ServerConfiguration{
config := &schema.Configuration{
Server: schema.ServerConfiguration{
Path: "apple",
},
}
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
ValidateServer(config, validator)
assert.Equal(t, "/apple", config.Path)
assert.Len(t, validator.Errors(), 0)
assert.Len(t, validator.Warnings(), 0)
assert.Equal(t, "/apple", config.Server.Path)
}
func TestShouldRaiseOnNegativeValues(t *testing.T) {
validator := schema.NewStructValidator()
config := schema.ServerConfiguration{
config := &schema.Configuration{
Server: schema.ServerConfiguration{
ReadBufferSize: -1,
WriteBufferSize: -1,
},
}
ValidateServer(&config, validator)
ValidateServer(config, validator)
require.Len(t, validator.Errors(), 2)
assert.EqualError(t, validator.Errors()[0], "server read buffer size must be above 0")
assert.EqualError(t, validator.Errors()[1], "server write buffer size must be above 0")
}
func TestShouldRaiseOnNonAlphanumericCharsInPath(t *testing.T) {
validator := schema.NewStructValidator()
config := schema.ServerConfiguration{
config := &schema.Configuration{
Server: schema.ServerConfiguration{
Path: "app le",
},
}
ValidateServer(&config, validator)
ValidateServer(config, validator)
require.Len(t, validator.Errors(), 1)
assert.Error(t, validator.Errors()[0], "server path must only be alpha numeric characters")
}
func TestShouldRaiseOnForwardSlashInPath(t *testing.T) {
validator := schema.NewStructValidator()
config := schema.ServerConfiguration{
config := &schema.Configuration{
Server: schema.ServerConfiguration{
Path: "app/le",
},
}
ValidateServer(&config, validator)
ValidateServer(config, validator)
assert.Len(t, validator.Errors(), 1)
assert.Error(t, validator.Errors()[0], "server path must not contain any forward slashes")
}
func TestShouldValidateAndUpdateHost(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.Host = ""
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, "0.0.0.0", config.Server.Host)
}
func TestShouldRaiseErrorWhenTLSCertWithoutKeyIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.TLS.Certificate = testTLSCert
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 1)
assert.EqualError(t, validator.Errors()[0], "server: no TLS key provided to accompany the TLS certificate, please configure the 'server.tls.key' option")
}
func TestShouldRaiseErrorWhenTLSKeyWithoutCertIsProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.TLS.Key = testTLSKey
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 1)
assert.EqualError(t, validator.Errors()[0], "server: no TLS certificate provided to accompany the TLS key, please configure the 'server.tls.certificate' option")
}
func TestShouldNotRaiseErrorWhenBothTLSCertificateAndKeyAreProvided(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.TLS.Certificate = testTLSCert
config.Server.TLS.Key = testTLSKey
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
}
func TestShouldNotUpdateConfig(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9090, config.Server.Port)
assert.Equal(t, loopback, config.Server.Host)
}
func TestShouldValidateAndUpdatePort(t *testing.T) {
validator := schema.NewStructValidator()
config := newDefaultConfig()
config.Server.Port = 0
ValidateServer(&config, validator)
require.Len(t, validator.Errors(), 0)
assert.Equal(t, 9091, config.Server.Port)
}

View File

@ -167,7 +167,7 @@ func StartServer(configuration schema.Configuration, providers middlewares.Provi
WriteBufferSize: configuration.Server.WriteBufferSize,
}
addrPattern := net.JoinHostPort(configuration.Host, strconv.Itoa(configuration.Port))
addrPattern := net.JoinHostPort(configuration.Server.Host, strconv.Itoa(configuration.Server.Port))
listener, err := net.Listen("tcp", addrPattern)
if err != nil {
@ -191,9 +191,9 @@ func StartServer(configuration schema.Configuration, providers middlewares.Provi
}
}
if configuration.TLSCert != "" && configuration.TLSKey != "" {
if configuration.Server.TLS.Certificate != "" && configuration.Server.TLS.Key != "" {
logger.Infof("Authelia is listening for TLS connections on %s%s", addrPattern, configuration.Server.Path)
logger.Fatal(server.ServeTLS(listener, configuration.TLSCert, configuration.TLSKey))
logger.Fatal(server.ServeTLS(listener, configuration.Server.TLS.Certificate, configuration.Server.TLS.Key))
} else {
logger.Infof("Authelia is listening for non-TLS connections on %s%s", addrPattern, configuration.Server.Path)
logger.Fatal(server.Serve(listener))

View File

@ -3,19 +3,19 @@
# Authelia minimal configuration #
###############################################################
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
theme: grey
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
ldap:
implementation: activedirectory

View File

@ -3,9 +3,11 @@
# Authelia minimal configuration #
###############################################################
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -3,9 +3,11 @@
# Authelia minimal configuration #
###############################################################
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: trace
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,15 +3,17 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: unsecure_secret
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,15 +3,17 @@
# Authelia configuration #
###############################################################
jwt_secret: unsecure_secret
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
totp:
issuer: authelia.com

View File

@ -3,19 +3,19 @@
# Authelia minimal configuration #
###############################################################
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
theme: dark
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
ldap:
url: ldaps://openldap

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,9 +3,11 @@
# Authelia minimal configuration #
###############################################################
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -3,9 +3,11 @@
# Authelia minimal configuration #
###############################################################
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -1,7 +1,9 @@
---
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -1,7 +1,9 @@
---
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: unsecure_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,18 +3,18 @@
# Authelia minimal configuration #
###############################################################
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
jwt_secret: unsecure_secret
server:
port: 9091
path: auth
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: very_important_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080/
jwt_secret: very_important_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,17 +3,18 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: unsecure_secret
default_redirection_url: https://home.example.com:8080/
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
default_redirection_url: https://home.example.com:8080/
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,12 +3,14 @@
# Authelia minimal configuration #
###############################################################
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
theme: auto
server:
port: 9091
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug

View File

@ -3,15 +3,17 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: unsecure_secret
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,15 +3,17 @@
# Authelia minimal configuration #
###############################################################
jwt_secret: unsecure_secret
server:
port: 9091
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /config/users.yml

View File

@ -3,15 +3,17 @@
# Authelia configuration #
###############################################################
default_redirection_url: https://home.example.com:8080
server:
port: 443
tls_cert: /config/ssl/cert.pem
tls_key: /config/ssl/key.pem
tls:
certificate: /config/ssl/cert.pem
key: /config/ssl/key.pem
log:
level: debug
default_redirection_url: https://home.example.com:8080
authentication_backend:
ldap:
url: ldaps://ldap-service

View File

@ -46,16 +46,13 @@ const (
unknown = "unknown"
)
// ErrTimeoutReached error thrown when a timeout is reached.
var ErrTimeoutReached = errors.New("timeout reached")
var parseDurationRegexp = regexp.MustCompile(`^(?P<Duration>[1-9]\d*?)(?P<Unit>[smhdwMy])?$`)
var (
reDuration = regexp.MustCompile(`^(?P<Duration>[1-9]\d*?)(?P<Unit>[smhdwMy])?$`)
)
// AlphaNumericCharacters are literally just valid alphanumeric chars.
var AlphaNumericCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
// ErrTLSVersionNotSupported returned when an unknown TLS version supplied.
var ErrTLSVersionNotSupported = errors.New("supplied TLS version isn't supported")
var htmlEscaper = strings.NewReplacer(
"&", "&amp;",
"<", "&lt;",
@ -63,3 +60,9 @@ var htmlEscaper = strings.NewReplacer(
`"`, "&#34;",
"'", "&#39;",
)
// ErrTimeoutReached error thrown when a timeout is reached.
var ErrTimeoutReached = errors.New("timeout reached")
// ErrTLSVersionNotSupported returned when an unknown TLS version supplied.
var ErrTLSVersionNotSupported = errors.New("supplied TLS version isn't supported")

View File

@ -13,7 +13,7 @@ import (
func ParseDurationString(input string) (time.Duration, error) {
var duration time.Duration
matches := parseDurationRegexp.FindStringSubmatch(input)
matches := reDuration.FindStringSubmatch(input)
switch {
case len(matches) == 3 && matches[2] != "":