mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
[MISC] Update durations to notation format and housekeeping (#824)
* added regulation validator * made regulations find_time and ban_time values duration notation strings * added DefaultRegulationConfiguration for the validator * made session expiration and inactivity values duration notation strings * TOTP period does not need to be converted because adjustment should be discouraged * moved TOTP defaults to DefaultTOTPConfiguration and removed the consts * arranged the root config validator in configuration file order * adjusted tests for the changes * moved duration notation docs to root of configuration * added references to duration notation where applicable * project wide gofmt and goimports: * run gofmt * run goimports -local github.com/authelia/authelia -w on all files * Make jwt_secret error uniform and add tests * now at 100% coverage for internal/configuration/validator/configuration.go
This commit is contained in:
parent
9800421b88
commit
8aade7f40e
|
@ -8,8 +8,9 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HostEntry represents an entry in /etc/hosts
|
// HostEntry represents an entry in /etc/hosts
|
||||||
|
|
|
@ -3,9 +3,10 @@ package main
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildAutheliaBinary() {
|
func buildAutheliaBinary() {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dockerPullCommandLine = "docker-compose -p authelia -f internal/suites/docker-compose.yml " +
|
const dockerPullCommandLine = "docker-compose -p authelia -f internal/suites/docker-compose.yml " +
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var arch string
|
var arch string
|
||||||
|
|
|
@ -3,9 +3,10 @@ package main
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServeCmd serve authelia with the provided configuration
|
// ServeCmd serve authelia with the provided configuration
|
||||||
|
|
|
@ -11,10 +11,11 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/suites"
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/suites"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotAvailableSuite error raised when suite is not available.
|
// ErrNotAvailableSuite error raised when suite is not available.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"os"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunUnitTest run the unit tests
|
// RunUnitTest run the unit tests
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/internal/commands"
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/commands"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logLevel string
|
var logLevel string
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/suites"
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/otiai10/copy"
|
"github.com/otiai10/copy"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/suites"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tmpDirectory = "/tmp/authelia/suites/"
|
var tmpDirectory = "/tmp/authelia/suites/"
|
||||||
|
|
|
@ -6,6 +6,9 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
"github.com/authelia/authelia/internal/commands"
|
"github.com/authelia/authelia/internal/commands"
|
||||||
|
@ -18,8 +21,6 @@ import (
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var configPathFlag string
|
var configPathFlag string
|
||||||
|
@ -50,7 +51,6 @@ func startServer() {
|
||||||
case "debug":
|
case "debug":
|
||||||
logging.Logger().Info("Logging severity set to debug")
|
logging.Logger().Info("Logging severity set to debug")
|
||||||
logging.SetLevel(logrus.DebugLevel)
|
logging.SetLevel(logrus.DebugLevel)
|
||||||
break
|
|
||||||
case "trace":
|
case "trace":
|
||||||
logging.Logger().Info("Logging severity set to trace")
|
logging.Logger().Info("Logging severity set to trace")
|
||||||
logging.SetLevel(logrus.TraceLevel)
|
logging.SetLevel(logrus.TraceLevel)
|
||||||
|
|
|
@ -262,14 +262,14 @@ session:
|
||||||
secret: insecure_session_secret
|
secret: insecure_session_secret
|
||||||
|
|
||||||
# The time in seconds before the cookie expires and session is reset.
|
# The time in seconds before the cookie expires and session is reset.
|
||||||
expiration: 3600 # 1 hour
|
expiration: 1h
|
||||||
|
|
||||||
# The inactivity time in seconds before the session is reset.
|
# The inactivity time in seconds before the session is reset.
|
||||||
inactivity: 300 # 5 minutes
|
inactivity: 5m
|
||||||
|
|
||||||
# The remember me duration.
|
# The remember me duration.
|
||||||
# Value of 0 disables remember me.
|
# Value of 0 disables remember me.
|
||||||
# Value is in seconds, or duration notation. See: https://docs.authelia.com/configuration/session.html#duration-notation
|
# Value is in seconds, or duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
# Longer periods are considered less secure because a stolen cookie will last longer giving attackers more time to spy
|
# Longer periods are considered less secure because a stolen cookie will last longer giving attackers more time to spy
|
||||||
# or attack. Currently the default is 1M or 1 month.
|
# or attack. Currently the default is 1M or 1 month.
|
||||||
remember_me_duration: 1M
|
remember_me_duration: 1M
|
||||||
|
@ -300,10 +300,12 @@ regulation:
|
||||||
|
|
||||||
# The time range during which the user can attempt login before being banned.
|
# The time range during which the user can attempt login before being banned.
|
||||||
# The user is banned if the authentication failed 'max_retries' times in a 'find_time' seconds window.
|
# The user is banned if the authentication failed 'max_retries' times in a 'find_time' seconds window.
|
||||||
find_time: 120
|
# Find Time accepts duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
|
find_time: 2m
|
||||||
|
|
||||||
# The length of time before a banned user can login again.
|
# The length of time before a banned user can login again.
|
||||||
ban_time: 300
|
# Ban Time accepts duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
|
ban_time: 5m
|
||||||
|
|
||||||
# Configuration of the storage backend used to store data and secrets.
|
# Configuration of the storage backend used to store data and secrets.
|
||||||
#
|
#
|
||||||
|
|
|
@ -14,3 +14,27 @@ When running **Authelia**, you can specify your configuration by passing
|
||||||
the file path as shown below.
|
the file path as shown below.
|
||||||
|
|
||||||
$ authelia --config config.custom.yml
|
$ authelia --config config.custom.yml
|
||||||
|
|
||||||
|
## Duration Notation Format
|
||||||
|
|
||||||
|
We have implemented a string based notation for configuration options that take a duration. This section describes its
|
||||||
|
usage. You can use this implementation in: session for expiration, inactivity, and remember_me_duration; and regulation
|
||||||
|
for ban_time, and find_time. This notation also supports just providing the number of seconds instead.
|
||||||
|
|
||||||
|
The notation is comprised of a number which must be positive and not have leading zeros, followed by a letter
|
||||||
|
denoting the unit of time measurement. The table below describes the units of time and the associated letter.
|
||||||
|
|
||||||
|
|Unit |Associated Letter|
|
||||||
|
|:-----:|:---------------:|
|
||||||
|
|Years |y |
|
||||||
|
|Months |M |
|
||||||
|
|Weeks |w |
|
||||||
|
|Days |d |
|
||||||
|
|Hours |h |
|
||||||
|
|Minutes|m |
|
||||||
|
|Seconds|s |
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
* 1 hour and 30 minutes: 90m
|
||||||
|
* 1 day: 1d
|
||||||
|
* 10 hours: 10h
|
|
@ -20,8 +20,15 @@ regulation:
|
||||||
|
|
||||||
# The time range during which the user can attempt login before being banned.
|
# The time range during which the user can attempt login before being banned.
|
||||||
# The user is banned if the authentication failed `max_retries` times in a `find_time` seconds window.
|
# The user is banned if the authentication failed `max_retries` times in a `find_time` seconds window.
|
||||||
find_time: 120
|
# Find Time accepts duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
|
find_time: 2m
|
||||||
|
|
||||||
# The length of time before a banned user can sign in again.
|
# The length of time before a banned user can sign in again.
|
||||||
ban_time: 300
|
# Find Time accepts duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
|
ban_time: 5m
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Duration Notation
|
||||||
|
|
||||||
|
The configuration parameters find_time, and ban_time use duration notation. See the documentation
|
||||||
|
for [duration notation format](index.md#duration-notation-format) for more information.
|
|
@ -27,14 +27,14 @@ session:
|
||||||
secret: unsecure_session_secret
|
secret: unsecure_session_secret
|
||||||
|
|
||||||
# The time in seconds before the cookie expires and session is reset.
|
# The time in seconds before the cookie expires and session is reset.
|
||||||
expiration: 3600 # 1 hour
|
expiration: 1h
|
||||||
|
|
||||||
# The inactivity time in seconds before the session is reset.
|
# The inactivity time in seconds before the session is reset.
|
||||||
inactivity: 300 # 5 minutes
|
inactivity: 5m
|
||||||
|
|
||||||
# The remember me duration.
|
# The remember me duration.
|
||||||
# Value of 0 disables remember me.
|
# Value of 0 disables remember me.
|
||||||
# Value is in seconds, or duration notation. See: https://docs.authelia.com/configuration/session.html#duration-notation
|
# Value is in seconds, or duration notation. See: https://docs.authelia.com/configuration/index.html#duration-notation-format
|
||||||
# Longer periods are considered less secure because a stolen cookie will last longer giving attackers more time to spy
|
# Longer periods are considered less secure because a stolen cookie will last longer giving attackers more time to spy
|
||||||
# or attack. Currently the default is 1M or 1 month.
|
# or attack. Currently the default is 1M or 1 month.
|
||||||
remember_me_duration: 1M
|
remember_me_duration: 1M
|
||||||
|
@ -57,28 +57,7 @@ session:
|
||||||
Configuration of this section has an impact on security. You should read notes in
|
Configuration of this section has an impact on security. You should read notes in
|
||||||
[security measures](../security/measures.md#session-security) for more information.
|
[security measures](../security/measures.md#session-security) for more information.
|
||||||
|
|
||||||
# Duration Notation
|
### Duration Notation
|
||||||
|
|
||||||
We have implemented a string based notation for configuration options that take a duration. This section describes its
|
The configuration parameters expiration, inactivity, and remember_me_duration use duration notation. See the documentation
|
||||||
usage.
|
for [duration notation format](index.md#duration-notation-format) for more information.
|
||||||
|
|
||||||
**NOTE:** At the time of this writing, only remember_me_duration uses this value type. But we plan to change expiration
|
|
||||||
and inactivity.
|
|
||||||
|
|
||||||
The notation is comprised of a number which must be positive and not have leading zeros, followed by a letter
|
|
||||||
denoting the unit of time measurement. The table below describes the units of time and the associated letter.
|
|
||||||
|
|
||||||
|Unit |Associated Letter|
|
|
||||||
|:-----:|:---------------:|
|
|
||||||
|Years |y |
|
|
||||||
|Months |M |
|
|
||||||
|Weeks |w |
|
|
||||||
|Days |d |
|
|
||||||
|Hours |h |
|
|
||||||
|Minutes|m |
|
|
||||||
|Seconds|s |
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
* 1 hour and 30 minutes: 90m
|
|
||||||
* 1 day: 1d
|
|
||||||
* 10 hours: 10h
|
|
|
@ -8,8 +8,9 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileUserProvider is a provider reading details from a file.
|
// FileUserProvider is a provider reading details from a file.
|
||||||
|
|
|
@ -7,8 +7,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WithDatabase(content []byte, f func(path string)) {
|
func WithDatabase(content []byte, f func(path string)) {
|
||||||
|
|
|
@ -6,9 +6,10 @@ package authentication
|
||||||
|
|
||||||
import (
|
import (
|
||||||
tls "crypto/tls"
|
tls "crypto/tls"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
ldap_v3 "github.com/go-ldap/ldap/v3"
|
ldap_v3 "github.com/go-ldap/ldap/v3"
|
||||||
gomock "github.com/golang/mock/gomock"
|
gomock "github.com/golang/mock/gomock"
|
||||||
reflect "reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockLDAPConnection is a mock of LDAPConnection interface
|
// MockLDAPConnection is a mock of LDAPConnection interface
|
||||||
|
|
|
@ -6,9 +6,10 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-ldap/ldap/v3"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/logging"
|
"github.com/authelia/authelia/internal/logging"
|
||||||
"github.com/go-ldap/ldap/v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LDAPUserProvider is a provider using a LDAP or AD as a user database.
|
// LDAPUserProvider is a provider using a LDAP or AD as a user database.
|
||||||
|
|
|
@ -3,11 +3,12 @@ package authentication
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/go-ldap/ldap/v3"
|
"github.com/go-ldap/ldap/v3"
|
||||||
gomock "github.com/golang/mock/gomock"
|
gomock "github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
|
func TestShouldCreateRawConnectionWhenSchemeIsLDAP(t *testing.T) {
|
||||||
|
|
|
@ -6,8 +6,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/simia-tech/crypt"
|
"github.com/simia-tech/crypt"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PasswordHash represents all characteristics of a password hash.
|
// PasswordHash represents all characteristics of a password hash.
|
||||||
|
|
|
@ -4,11 +4,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/simia-tech/crypt"
|
"github.com/simia-tech/crypt"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldHashSHA512Password(t *testing.T) {
|
func TestShouldHashSHA512Password(t *testing.T) {
|
||||||
|
|
|
@ -3,9 +3,10 @@ package commands
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration"
|
"github.com/authelia/authelia/internal/configuration"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var MigrateCmd *cobra.Command
|
var MigrateCmd *cobra.Command
|
||||||
|
|
|
@ -8,9 +8,10 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/models"
|
"github.com/authelia/authelia/internal/models"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var configurationPath string
|
var configurationPath string
|
||||||
|
|
|
@ -5,12 +5,13 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/models"
|
|
||||||
"github.com/authelia/authelia/internal/storage"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/models"
|
||||||
|
"github.com/authelia/authelia/internal/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
var mongoURL string
|
var mongoURL string
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/configuration/validator"
|
"github.com/authelia/authelia/internal/configuration/validator"
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func check(e error) {
|
func check(e error) {
|
||||||
|
|
|
@ -3,6 +3,12 @@ package schema
|
||||||
// RegulationConfiguration represents the configuration related to regulation.
|
// RegulationConfiguration represents the configuration related to regulation.
|
||||||
type RegulationConfiguration struct {
|
type RegulationConfiguration struct {
|
||||||
MaxRetries int `mapstructure:"max_retries"`
|
MaxRetries int `mapstructure:"max_retries"`
|
||||||
FindTime int64 `mapstructure:"find_time"`
|
FindTime string `mapstructure:"find_time"`
|
||||||
BanTime int64 `mapstructure:"ban_time"`
|
BanTime string `mapstructure:"ban_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var DefaultRegulationConfiguration = RegulationConfiguration{
|
||||||
|
MaxRetries: 3,
|
||||||
|
FindTime: "2m",
|
||||||
|
BanTime: "5m",
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,10 @@ type RedisSessionConfiguration struct {
|
||||||
|
|
||||||
// SessionConfiguration represents the configuration related to user sessions.
|
// SessionConfiguration represents the configuration related to user sessions.
|
||||||
type SessionConfiguration struct {
|
type SessionConfiguration struct {
|
||||||
// TODO(james-d-elliott): Convert to duration notation (Both Expiration and Activity need to be strings, and default needs to be changed)
|
|
||||||
Name string `mapstructure:"name"`
|
Name string `mapstructure:"name"`
|
||||||
Secret string `mapstructure:"secret"`
|
Secret string `mapstructure:"secret"`
|
||||||
Expiration int64 `mapstructure:"expiration"` // Expiration in seconds
|
Expiration string `mapstructure:"expiration"`
|
||||||
Inactivity int64 `mapstructure:"inactivity"` // Inactivity in seconds
|
Inactivity string `mapstructure:"inactivity"`
|
||||||
RememberMeDuration string `mapstructure:"remember_me_duration"`
|
RememberMeDuration string `mapstructure:"remember_me_duration"`
|
||||||
Domain string `mapstructure:"domain"`
|
Domain string `mapstructure:"domain"`
|
||||||
Redis *RedisSessionConfiguration `mapstructure:"redis"`
|
Redis *RedisSessionConfiguration `mapstructure:"redis"`
|
||||||
|
@ -23,6 +22,7 @@ type SessionConfiguration struct {
|
||||||
// DefaultSessionConfiguration is the default session configuration
|
// DefaultSessionConfiguration is the default session configuration
|
||||||
var DefaultSessionConfiguration = SessionConfiguration{
|
var DefaultSessionConfiguration = SessionConfiguration{
|
||||||
Name: "authelia_session",
|
Name: "authelia_session",
|
||||||
Expiration: 3600,
|
Expiration: "1h",
|
||||||
|
Inactivity: "5m",
|
||||||
RememberMeDuration: "1M",
|
RememberMeDuration: "1M",
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,10 @@ type TOTPConfiguration struct {
|
||||||
Period int `mapstructure:"period"`
|
Period int `mapstructure:"period"`
|
||||||
Skew *int `mapstructure:"skew"`
|
Skew *int `mapstructure:"skew"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultOtpSkew = 1
|
||||||
|
var DefaultTOTPConfiguration = TOTPConfiguration{
|
||||||
|
Issuer: "Authelia",
|
||||||
|
Period: 30,
|
||||||
|
Skew: &defaultOtpSkew,
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,11 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldRaiseErrorsWhenNoBackendProvided(t *testing.T) {
|
func TestShouldRaiseErrorsWhenNoBackendProvided(t *testing.T) {
|
||||||
|
|
|
@ -20,16 +20,20 @@ func Validate(configuration *schema.Configuration, validator *schema.StructValid
|
||||||
configuration.Port = defaultPort
|
configuration.Port = defaultPort
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.LogLevel == "" {
|
|
||||||
configuration.LogLevel = defaultLogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
if configuration.TLSKey != "" && configuration.TLSCert == "" {
|
if configuration.TLSKey != "" && configuration.TLSCert == "" {
|
||||||
validator.Push(fmt.Errorf("No TLS certificate provided, please check the \"tls_cert\" which has been configured"))
|
validator.Push(fmt.Errorf("No TLS certificate provided, please check the \"tls_cert\" which has been configured"))
|
||||||
} else if configuration.TLSKey == "" && configuration.TLSCert != "" {
|
} else if configuration.TLSKey == "" && configuration.TLSCert != "" {
|
||||||
validator.Push(fmt.Errorf("No TLS key provided, please check the \"tls_key\" which has been configured"))
|
validator.Push(fmt.Errorf("No TLS key provided, please check the \"tls_key\" which has been configured"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if configuration.LogLevel == "" {
|
||||||
|
configuration.LogLevel = defaultLogLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
if configuration.JWTSecret == "" {
|
||||||
|
validator.Push(fmt.Errorf("Provide a JWT secret using \"jwt_secret\" key"))
|
||||||
|
}
|
||||||
|
|
||||||
if configuration.DefaultRedirectionURL != "" {
|
if configuration.DefaultRedirectionURL != "" {
|
||||||
_, err := url.ParseRequestURI(configuration.DefaultRedirectionURL)
|
_, err := url.ParseRequestURI(configuration.DefaultRedirectionURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -37,27 +41,29 @@ func Validate(configuration *schema.Configuration, validator *schema.StructValid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.JWTSecret == "" {
|
|
||||||
validator.Push(fmt.Errorf("Provide a JWT secret using `jwt_secret` key"))
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateAuthenticationBackend(&configuration.AuthenticationBackend, validator)
|
|
||||||
ValidateSession(&configuration.Session, validator)
|
|
||||||
|
|
||||||
if configuration.TOTP == nil {
|
if configuration.TOTP == nil {
|
||||||
configuration.TOTP = &schema.TOTPConfiguration{}
|
configuration.TOTP = &schema.TOTPConfiguration{}
|
||||||
}
|
}
|
||||||
ValidateTOTP(configuration.TOTP, validator)
|
ValidateTOTP(configuration.TOTP, validator)
|
||||||
|
|
||||||
|
ValidateAuthenticationBackend(&configuration.AuthenticationBackend, validator)
|
||||||
|
|
||||||
|
if configuration.AccessControl.DefaultPolicy == "" {
|
||||||
|
configuration.AccessControl.DefaultPolicy = "deny"
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidateSession(&configuration.Session, validator)
|
||||||
|
|
||||||
|
if configuration.Regulation == nil {
|
||||||
|
configuration.Regulation = &schema.RegulationConfiguration{}
|
||||||
|
}
|
||||||
|
ValidateRegulation(configuration.Regulation, validator)
|
||||||
|
|
||||||
|
ValidateStorage(configuration.Storage, validator)
|
||||||
|
|
||||||
if configuration.Notifier == nil {
|
if configuration.Notifier == nil {
|
||||||
validator.Push(fmt.Errorf("A notifier configuration must be provided"))
|
validator.Push(fmt.Errorf("A notifier configuration must be provided"))
|
||||||
} else {
|
} else {
|
||||||
ValidateNotifier(configuration.Notifier, validator)
|
ValidateNotifier(configuration.Notifier, validator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.AccessControl.DefaultPolicy == "" {
|
|
||||||
configuration.AccessControl.DefaultPolicy = "deny"
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateStorage(configuration.Storage, validator)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newDefaultConfig() schema.Configuration {
|
func newDefaultConfig() schema.Configuration {
|
||||||
|
@ -129,3 +130,23 @@ func TestShouldNotRaiseErrorWhenBothTLSCertificateAndKeyAreProvided(t *testing.T
|
||||||
Validate(&config, validator)
|
Validate(&config, validator)
|
||||||
require.Len(t, validator.Errors(), 0)
|
require.Len(t, validator.Errors(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShouldRaiseErrorWithUndefinedJWTSecretKey(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultConfig()
|
||||||
|
config.JWTSecret = ""
|
||||||
|
|
||||||
|
Validate(&config, validator)
|
||||||
|
require.Len(t, validator.Errors(), 1)
|
||||||
|
assert.EqualError(t, validator.Errors()[0], "Provide a JWT secret using \"jwt_secret\" key")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldRaiseErrorWithBadDefaultRedirectionURL(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultConfig()
|
||||||
|
config.DefaultRedirectionURL = "abc"
|
||||||
|
|
||||||
|
Validate(&config, validator)
|
||||||
|
require.Len(t, validator.Errors(), 1)
|
||||||
|
assert.EqualError(t, validator.Errors()[0], "Unable to parse default redirection url")
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import "github.com/authelia/authelia/internal/configuration/schema"
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
import "fmt"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
)
|
||||||
|
|
||||||
// ValidateSession validates and update session configuration.
|
// ValidateSession validates and update session configuration.
|
||||||
func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *schema.StructValidator) {
|
func ValidateNotifier(configuration *schema.NotifierConfiguration, validator *schema.StructValidator) {
|
||||||
|
|
|
@ -3,8 +3,9 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NotifierSuite struct {
|
type NotifierSuite struct {
|
||||||
|
|
30
internal/configuration/validator/regulation.go
Normal file
30
internal/configuration/validator/regulation.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateSession validates and update session configuration.
|
||||||
|
func ValidateRegulation(configuration *schema.RegulationConfiguration, validator *schema.StructValidator) {
|
||||||
|
if configuration.FindTime == "" {
|
||||||
|
configuration.FindTime = schema.DefaultRegulationConfiguration.FindTime // 2 min
|
||||||
|
}
|
||||||
|
if configuration.BanTime == "" {
|
||||||
|
configuration.BanTime = schema.DefaultRegulationConfiguration.BanTime // 5 min
|
||||||
|
}
|
||||||
|
findTime, err := utils.ParseDurationString(configuration.FindTime)
|
||||||
|
if err != nil {
|
||||||
|
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing regulation find_time string: %s", err)))
|
||||||
|
}
|
||||||
|
banTime, err := utils.ParseDurationString(configuration.BanTime)
|
||||||
|
if err != nil {
|
||||||
|
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing regulation ban_time string: %s", err)))
|
||||||
|
}
|
||||||
|
if findTime > banTime {
|
||||||
|
validator.Push(errors.New(fmt.Sprintf("find_time cannot be greater than ban_time")))
|
||||||
|
}
|
||||||
|
}
|
45
internal/configuration/validator/regulation_test.go
Normal file
45
internal/configuration/validator/regulation_test.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDefaultRegulationConfig() schema.RegulationConfiguration {
|
||||||
|
config := schema.RegulationConfiguration{}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldSetDefaultRegulationBanTime(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultRegulationConfig()
|
||||||
|
|
||||||
|
ValidateRegulation(&config, validator)
|
||||||
|
|
||||||
|
assert.Len(t, validator.Errors(), 0)
|
||||||
|
assert.Equal(t, schema.DefaultRegulationConfiguration.BanTime, config.BanTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldSetDefaultRegulationFindTime(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultRegulationConfig()
|
||||||
|
|
||||||
|
ValidateRegulation(&config, validator)
|
||||||
|
|
||||||
|
assert.Len(t, validator.Errors(), 0)
|
||||||
|
assert.Equal(t, schema.DefaultRegulationConfiguration.FindTime, config.FindTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldRaiseErrorWhenFindTimeLessThanBanTime(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultRegulationConfig()
|
||||||
|
config.FindTime = "1m"
|
||||||
|
config.BanTime = "10s"
|
||||||
|
ValidateRegulation(&config, validator)
|
||||||
|
|
||||||
|
assert.Len(t, validator.Errors(), 1)
|
||||||
|
assert.EqualError(t, validator.Errors()[0], "find_time cannot be greater than ban_time")
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package validator
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
@ -17,24 +18,22 @@ func ValidateSession(configuration *schema.SessionConfiguration, validator *sche
|
||||||
validator.Push(errors.New("Set secret of the session object"))
|
validator.Push(errors.New("Set secret of the session object"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
if configuration.Expiration == "" {
|
||||||
if configuration.Expiration == 0 {
|
|
||||||
configuration.Expiration = schema.DefaultSessionConfiguration.Expiration // 1 hour
|
configuration.Expiration = schema.DefaultSessionConfiguration.Expiration // 1 hour
|
||||||
} else if configuration.Expiration < 1 {
|
} else if _, err := utils.ParseDurationString(configuration.Expiration); err != nil {
|
||||||
validator.Push(errors.New("Set expiration of the session above 0"))
|
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing session expiration string: %s", err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
if configuration.Inactivity == "" {
|
||||||
if configuration.Inactivity < 0 {
|
configuration.Inactivity = schema.DefaultSessionConfiguration.Inactivity // 5 min
|
||||||
validator.Push(errors.New("Set inactivity of the session to 0 or above"))
|
} else if _, err := utils.ParseDurationString(configuration.Inactivity); err != nil {
|
||||||
|
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing session inactivity string: %s", err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.RememberMeDuration == "" {
|
if configuration.RememberMeDuration == "" {
|
||||||
configuration.RememberMeDuration = schema.DefaultSessionConfiguration.RememberMeDuration
|
configuration.RememberMeDuration = schema.DefaultSessionConfiguration.RememberMeDuration // 1 month
|
||||||
} else {
|
} else if _, err := utils.ParseDurationString(configuration.RememberMeDuration); err != nil {
|
||||||
if _, err := utils.ParseDurationString(configuration.RememberMeDuration); err != nil {
|
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing session remember_me_duration string: %s", err)))
|
||||||
validator.Push(errors.New(fmt.Sprintf("Error occurred parsing remember_me_duration string: %s", err)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.Domain == "" {
|
if configuration.Domain == "" {
|
||||||
|
|
|
@ -3,8 +3,9 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newDefaultSessionConfig() schema.SessionConfiguration {
|
func newDefaultSessionConfig() schema.SessionConfiguration {
|
||||||
|
@ -21,7 +22,27 @@ func TestShouldSetDefaultSessionName(t *testing.T) {
|
||||||
ValidateSession(&config, validator)
|
ValidateSession(&config, validator)
|
||||||
|
|
||||||
assert.Len(t, validator.Errors(), 0)
|
assert.Len(t, validator.Errors(), 0)
|
||||||
assert.Equal(t, "authelia_session", config.Name)
|
assert.Equal(t, schema.DefaultSessionConfiguration.Name, config.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldSetDefaultSessionInactivity(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultSessionConfig()
|
||||||
|
|
||||||
|
ValidateSession(&config, validator)
|
||||||
|
|
||||||
|
assert.Len(t, validator.Errors(), 0)
|
||||||
|
assert.Equal(t, schema.DefaultSessionConfiguration.Inactivity, config.Inactivity)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldSetDefaultSessionExpiration(t *testing.T) {
|
||||||
|
validator := schema.NewStructValidator()
|
||||||
|
config := newDefaultSessionConfig()
|
||||||
|
|
||||||
|
ValidateSession(&config, validator)
|
||||||
|
|
||||||
|
assert.Len(t, validator.Errors(), 0)
|
||||||
|
assert.Equal(t, schema.DefaultSessionConfiguration.Expiration, config.Expiration)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldRaiseErrorWhenRedisIsUsedAndPasswordNotSet(t *testing.T) {
|
func TestShouldRaiseErrorWhenRedisIsUsedAndPasswordNotSet(t *testing.T) {
|
||||||
|
@ -57,14 +78,14 @@ func TestShouldRaiseErrorWhenDomainNotSet(t *testing.T) {
|
||||||
func TestShouldRaiseErrorWhenBadInactivityAndExpirationSet(t *testing.T) {
|
func TestShouldRaiseErrorWhenBadInactivityAndExpirationSet(t *testing.T) {
|
||||||
validator := schema.NewStructValidator()
|
validator := schema.NewStructValidator()
|
||||||
config := newDefaultSessionConfig()
|
config := newDefaultSessionConfig()
|
||||||
config.Inactivity = -1
|
config.Inactivity = "-1"
|
||||||
config.Expiration = -1
|
config.Expiration = "-1"
|
||||||
|
|
||||||
ValidateSession(&config, validator)
|
ValidateSession(&config, validator)
|
||||||
|
|
||||||
assert.Len(t, validator.Errors(), 2)
|
assert.Len(t, validator.Errors(), 2)
|
||||||
assert.EqualError(t, validator.Errors()[0], "Set expiration of the session above 0")
|
assert.EqualError(t, validator.Errors()[0], "Error occurred parsing session expiration string: could not convert the input string of -1 into a duration")
|
||||||
assert.EqualError(t, validator.Errors()[1], "Set inactivity of the session to 0 or above")
|
assert.EqualError(t, validator.Errors()[1], "Error occurred parsing session inactivity string: could not convert the input string of -1 into a duration")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldRaiseErrorWhenBadRememberMeDurationSet(t *testing.T) {
|
func TestShouldRaiseErrorWhenBadRememberMeDurationSet(t *testing.T) {
|
||||||
|
@ -75,7 +96,7 @@ func TestShouldRaiseErrorWhenBadRememberMeDurationSet(t *testing.T) {
|
||||||
ValidateSession(&config, validator)
|
ValidateSession(&config, validator)
|
||||||
|
|
||||||
assert.Len(t, validator.Errors(), 1)
|
assert.Len(t, validator.Errors(), 1)
|
||||||
assert.EqualError(t, validator.Errors()[0], "Error occurred parsing remember_me_duration string: could not convert the input string of 1 year into a duration")
|
assert.EqualError(t, validator.Errors()[0], "Error occurred parsing session remember_me_duration string: could not convert the input string of 1 year into a duration")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldSetDefaultRememberMeDuration(t *testing.T) {
|
func TestShouldSetDefaultRememberMeDuration(t *testing.T) {
|
||||||
|
|
|
@ -3,8 +3,9 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageSuite struct {
|
type StorageSuite struct {
|
||||||
|
|
|
@ -2,27 +2,23 @@ package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultTOTPIssuer = "Authelia"
|
|
||||||
const DefaultTOTPPeriod = 30
|
|
||||||
const DefaultTOTPSkew = 1
|
|
||||||
|
|
||||||
// ValidateTOTP validates and update TOTP configuration.
|
// ValidateTOTP validates and update TOTP configuration.
|
||||||
func ValidateTOTP(configuration *schema.TOTPConfiguration, validator *schema.StructValidator) {
|
func ValidateTOTP(configuration *schema.TOTPConfiguration, validator *schema.StructValidator) {
|
||||||
if configuration.Issuer == "" {
|
if configuration.Issuer == "" {
|
||||||
configuration.Issuer = defaultTOTPIssuer
|
configuration.Issuer = schema.DefaultTOTPConfiguration.Issuer
|
||||||
}
|
}
|
||||||
if configuration.Period == 0 {
|
if configuration.Period == 0 {
|
||||||
configuration.Period = DefaultTOTPPeriod
|
configuration.Period = schema.DefaultTOTPConfiguration.Period
|
||||||
} else if configuration.Period < 0 {
|
} else if configuration.Period < 0 {
|
||||||
validator.Push(fmt.Errorf("TOTP Period must be 1 or more"))
|
validator.Push(fmt.Errorf("TOTP Period must be 1 or more"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if configuration.Skew == nil {
|
if configuration.Skew == nil {
|
||||||
var skew = DefaultTOTPSkew
|
configuration.Skew = schema.DefaultTOTPConfiguration.Skew
|
||||||
configuration.Skew = &skew
|
|
||||||
} else if *configuration.Skew < 0 {
|
} else if *configuration.Skew < 0 {
|
||||||
validator.Push(fmt.Errorf("TOTP Skew must be 0 or more"))
|
validator.Push(fmt.Errorf("TOTP Skew must be 0 or more"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@ package validator
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldSetDefaultTOTPValues(t *testing.T) {
|
func TestShouldSetDefaultTOTPValues(t *testing.T) {
|
||||||
|
@ -16,8 +17,8 @@ func TestShouldSetDefaultTOTPValues(t *testing.T) {
|
||||||
|
|
||||||
require.Len(t, validator.Errors(), 0)
|
require.Len(t, validator.Errors(), 0)
|
||||||
assert.Equal(t, "Authelia", config.Issuer)
|
assert.Equal(t, "Authelia", config.Issuer)
|
||||||
assert.Equal(t, DefaultTOTPSkew, *config.Skew)
|
assert.Equal(t, *schema.DefaultTOTPConfiguration.Skew, *config.Skew)
|
||||||
assert.Equal(t, DefaultTOTPPeriod, config.Period)
|
assert.Equal(t, schema.DefaultTOTPConfiguration.Period, config.Period)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestShouldRaiseErrorWhenInvalidTOTPMinimumValues(t *testing.T) {
|
func TestShouldRaiseErrorWhenInvalidTOTPMinimumValues(t *testing.T) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/duosecurity/duo_api_golang"
|
duoapi "github.com/duosecurity/duo_api_golang"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,9 +3,10 @@ package duo
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
duoapi "github.com/duosecurity/duo_api_golang"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
)
|
)
|
||||||
import "github.com/duosecurity/duo_api_golang"
|
|
||||||
|
|
||||||
// API interface wrapping duo api library for testing purpose
|
// API interface wrapping duo api library for testing purpose
|
||||||
type API interface {
|
type API interface {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfigurationSuite struct {
|
type ConfigurationSuite struct {
|
||||||
|
|
|
@ -3,12 +3,11 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/configuration/validator"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecondFactorAvailableMethodsFixture struct {
|
type SecondFactorAvailableMethodsFixture struct {
|
||||||
|
@ -31,13 +30,13 @@ func (s *SecondFactorAvailableMethodsFixture) TearDownTest() {
|
||||||
func (s *SecondFactorAvailableMethodsFixture) TestShouldServeDefaultMethods() {
|
func (s *SecondFactorAvailableMethodsFixture) TestShouldServeDefaultMethods() {
|
||||||
s.mock.Ctx.Configuration = schema.Configuration{
|
s.mock.Ctx.Configuration = schema.Configuration{
|
||||||
TOTP: &schema.TOTPConfiguration{
|
TOTP: &schema.TOTPConfiguration{
|
||||||
Period: validator.DefaultTOTPPeriod,
|
Period: schema.DefaultTOTPConfiguration.Period,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
expectedBody := ExtendedConfigurationBody{
|
expectedBody := ExtendedConfigurationBody{
|
||||||
AvailableMethods: []string{"totp", "u2f"},
|
AvailableMethods: []string{"totp", "u2f"},
|
||||||
SecondFactorEnabled: false,
|
SecondFactorEnabled: false,
|
||||||
TOTPPeriod: validator.DefaultTOTPPeriod,
|
TOTPPeriod: schema.DefaultTOTPConfiguration.Period,
|
||||||
}
|
}
|
||||||
ExtendedConfigurationGet(s.mock.Ctx)
|
ExtendedConfigurationGet(s.mock.Ctx)
|
||||||
s.mock.Assert200OK(s.T(), expectedBody)
|
s.mock.Assert200OK(s.T(), expectedBody)
|
||||||
|
@ -47,13 +46,13 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldServeDefaultMethodsAndMo
|
||||||
s.mock.Ctx.Configuration = schema.Configuration{
|
s.mock.Ctx.Configuration = schema.Configuration{
|
||||||
DuoAPI: &schema.DuoAPIConfiguration{},
|
DuoAPI: &schema.DuoAPIConfiguration{},
|
||||||
TOTP: &schema.TOTPConfiguration{
|
TOTP: &schema.TOTPConfiguration{
|
||||||
Period: validator.DefaultTOTPPeriod,
|
Period: schema.DefaultTOTPConfiguration.Period,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
expectedBody := ExtendedConfigurationBody{
|
expectedBody := ExtendedConfigurationBody{
|
||||||
AvailableMethods: []string{"totp", "u2f", "mobile_push"},
|
AvailableMethods: []string{"totp", "u2f", "mobile_push"},
|
||||||
SecondFactorEnabled: false,
|
SecondFactorEnabled: false,
|
||||||
TOTPPeriod: validator.DefaultTOTPPeriod,
|
TOTPPeriod: schema.DefaultTOTPConfiguration.Period,
|
||||||
}
|
}
|
||||||
ExtendedConfigurationGet(s.mock.Ctx)
|
ExtendedConfigurationGet(s.mock.Ctx)
|
||||||
s.mock.Assert200OK(s.T(), expectedBody)
|
s.mock.Assert200OK(s.T(), expectedBody)
|
||||||
|
@ -62,7 +61,7 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldServeDefaultMethodsAndMo
|
||||||
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsDisabledWhenNoRuleIsSetToTwoFactor() {
|
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsDisabledWhenNoRuleIsSetToTwoFactor() {
|
||||||
s.mock.Ctx.Configuration = schema.Configuration{
|
s.mock.Ctx.Configuration = schema.Configuration{
|
||||||
TOTP: &schema.TOTPConfiguration{
|
TOTP: &schema.TOTPConfiguration{
|
||||||
Period: validator.DefaultTOTPPeriod,
|
Period: schema.DefaultTOTPConfiguration.Period,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
||||||
|
@ -86,14 +85,14 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsDisab
|
||||||
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
||||||
AvailableMethods: []string{"totp", "u2f"},
|
AvailableMethods: []string{"totp", "u2f"},
|
||||||
SecondFactorEnabled: false,
|
SecondFactorEnabled: false,
|
||||||
TOTPPeriod: validator.DefaultTOTPPeriod,
|
TOTPPeriod: schema.DefaultTOTPConfiguration.Period,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabledWhenDefaultPolicySetToTwoFactor() {
|
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabledWhenDefaultPolicySetToTwoFactor() {
|
||||||
s.mock.Ctx.Configuration = schema.Configuration{
|
s.mock.Ctx.Configuration = schema.Configuration{
|
||||||
TOTP: &schema.TOTPConfiguration{
|
TOTP: &schema.TOTPConfiguration{
|
||||||
Period: validator.DefaultTOTPPeriod,
|
Period: schema.DefaultTOTPConfiguration.Period,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
||||||
|
@ -117,14 +116,14 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabl
|
||||||
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
||||||
AvailableMethods: []string{"totp", "u2f"},
|
AvailableMethods: []string{"totp", "u2f"},
|
||||||
SecondFactorEnabled: true,
|
SecondFactorEnabled: true,
|
||||||
TOTPPeriod: validator.DefaultTOTPPeriod,
|
TOTPPeriod: schema.DefaultTOTPConfiguration.Period,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabledWhenSomePolicySetToTwoFactor() {
|
func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabledWhenSomePolicySetToTwoFactor() {
|
||||||
s.mock.Ctx.Configuration = schema.Configuration{
|
s.mock.Ctx.Configuration = schema.Configuration{
|
||||||
TOTP: &schema.TOTPConfiguration{
|
TOTP: &schema.TOTPConfiguration{
|
||||||
Period: validator.DefaultTOTPPeriod,
|
Period: schema.DefaultTOTPConfiguration.Period,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
s.mock.Ctx.Providers.Authorizer = authorization.NewAuthorizer(schema.AccessControlConfiguration{
|
||||||
|
@ -148,7 +147,7 @@ func (s *SecondFactorAvailableMethodsFixture) TestShouldCheckSecondFactorIsEnabl
|
||||||
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
s.mock.Assert200OK(s.T(), ExtendedConfigurationBody{
|
||||||
AvailableMethods: []string{"totp", "u2f"},
|
AvailableMethods: []string{"totp", "u2f"},
|
||||||
SecondFactorEnabled: true,
|
SecondFactorEnabled: true,
|
||||||
TOTPPeriod: validator.DefaultTOTPPeriod,
|
TOTPPeriod: schema.DefaultTOTPConfiguration.Period,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,12 @@ import (
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
"github.com/authelia/authelia/internal/models"
|
"github.com/authelia/authelia/internal/models"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FirstFactorSuite struct {
|
type FirstFactorSuite struct {
|
||||||
|
|
|
@ -3,9 +3,10 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pquerna/otp/totp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/pquerna/otp/totp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// identityRetrieverFromSession retriever computing the identity from the cookie session.
|
// identityRetrieverFromSession retriever computing the identity from the cookie session.
|
||||||
|
|
|
@ -3,8 +3,9 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
)
|
)
|
||||||
|
|
||||||
var u2fConfig = &u2f.Config{
|
var u2fConfig = &u2f.Config{
|
||||||
|
|
|
@ -5,12 +5,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerRegisterU2FStep1Suite struct {
|
type HandlerRegisterU2FStep1Suite struct {
|
||||||
|
|
|
@ -4,8 +4,9 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SecondFactorU2FRegister handler validating the client has successfully validated the challenge
|
// SecondFactorU2FRegister handler validating the client has successfully validated the challenge
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/duo"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/duo"
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SecondFactorDuoPostSuite struct {
|
type SecondFactorDuoPostSuite struct {
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/authelia/authelia/internal/session"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
|
"github.com/authelia/authelia/internal/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerSignTOTPSuite struct {
|
type HandlerSignTOTPSuite struct {
|
||||||
|
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/tstranex/u2f"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SecondFactorU2FSignGet handler for initiating a signing request.
|
// SecondFactorU2FSignGet handler for initiating a signing request.
|
||||||
|
|
|
@ -3,9 +3,10 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerSignU2FStep1Suite struct {
|
type HandlerSignU2FStep1Suite struct {
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/authelia/authelia/internal/session"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
|
"github.com/authelia/authelia/internal/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HandlerSignU2FStep2Suite struct {
|
type HandlerSignU2FStep2Suite struct {
|
||||||
|
|
|
@ -6,9 +6,10 @@ import (
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StateGetSuite struct {
|
type StateGetSuite struct {
|
||||||
|
|
|
@ -5,11 +5,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadInfo(username string, storageProvider storage.Provider, preferences *UserPreferences, logger *logrus.Entry) []error {
|
func loadInfo(username string, storageProvider storage.Provider, preferences *UserPreferences, logger *logrus.Entry) []error {
|
||||||
|
|
|
@ -8,10 +8,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func isURLUnderProtectedDomain(url *url.URL, domain string) bool {
|
func isURLUnderProtectedDomain(url *url.URL, domain string) bool {
|
||||||
|
@ -155,8 +156,7 @@ func setForwardedHeaders(headers *fasthttp.ResponseHeader, username string, grou
|
||||||
// hasUserBeenInactiveLongEnough check whether the user has been inactive for too long.
|
// hasUserBeenInactiveLongEnough check whether the user has been inactive for too long.
|
||||||
func hasUserBeenInactiveLongEnough(ctx *middlewares.AutheliaCtx) (bool, error) {
|
func hasUserBeenInactiveLongEnough(ctx *middlewares.AutheliaCtx) (bool, error) {
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
maxInactivityPeriod := int64(ctx.Providers.SessionProvider.Inactivity.Seconds())
|
||||||
maxInactivityPeriod := ctx.Configuration.Session.Inactivity
|
|
||||||
if maxInactivityPeriod == 0 {
|
if maxInactivityPeriod == 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test getOriginalURL
|
// Test getOriginalURL
|
||||||
|
@ -469,8 +472,38 @@ func TestShouldDestroySessionWhenInactiveForTooLong(t *testing.T) {
|
||||||
clock := mocks.TestingClock{}
|
clock := mocks.TestingClock{}
|
||||||
clock.Set(time.Now())
|
clock.Set(time.Now())
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
mock.Ctx.Configuration.Session.Inactivity = "10"
|
||||||
mock.Ctx.Configuration.Session.Inactivity = 10
|
// Reload the session provider since the configuration is indirect
|
||||||
|
mock.Ctx.Providers.SessionProvider = session.NewProvider(mock.Ctx.Configuration.Session)
|
||||||
|
assert.Equal(t, time.Second*10, mock.Ctx.Providers.SessionProvider.Inactivity)
|
||||||
|
|
||||||
|
userSession := mock.Ctx.GetSession()
|
||||||
|
userSession.Username = "john"
|
||||||
|
userSession.AuthenticationLevel = authentication.TwoFactor
|
||||||
|
userSession.LastActivity = clock.Now().Add(-1 * time.Hour).Unix()
|
||||||
|
mock.Ctx.SaveSession(userSession)
|
||||||
|
|
||||||
|
mock.Ctx.Request.Header.Set("X-Original-URL", "https://two-factor.example.com")
|
||||||
|
|
||||||
|
VerifyGet(mock.Ctx)
|
||||||
|
|
||||||
|
// The session has been destroyed
|
||||||
|
newUserSession := mock.Ctx.GetSession()
|
||||||
|
assert.Equal(t, "", newUserSession.Username)
|
||||||
|
assert.Equal(t, authentication.NotAuthenticated, newUserSession.AuthenticationLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestShouldDestroySessionWhenInactiveForTooLongUsingDurationNotation(t *testing.T) {
|
||||||
|
mock := mocks.NewMockAutheliaCtx(t)
|
||||||
|
defer mock.Close()
|
||||||
|
|
||||||
|
clock := mocks.TestingClock{}
|
||||||
|
clock.Set(time.Now())
|
||||||
|
|
||||||
|
mock.Ctx.Configuration.Session.Inactivity = "10s"
|
||||||
|
// Reload the session provider since the configuration is indirect
|
||||||
|
mock.Ctx.Providers.SessionProvider = session.NewProvider(mock.Ctx.Configuration.Session)
|
||||||
|
assert.Equal(t, time.Second*10, mock.Ctx.Providers.SessionProvider.Inactivity)
|
||||||
|
|
||||||
userSession := mock.Ctx.GetSession()
|
userSession := mock.Ctx.GetSession()
|
||||||
userSession.Username = "john"
|
userSession.Username = "john"
|
||||||
|
@ -495,8 +528,7 @@ func TestShouldKeepSessionWhenUserCheckedRememberMeAndIsInactiveForTooLong(t *te
|
||||||
clock := mocks.TestingClock{}
|
clock := mocks.TestingClock{}
|
||||||
clock.Set(time.Now())
|
clock.Set(time.Now())
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
mock.Ctx.Configuration.Session.Inactivity = "10"
|
||||||
mock.Ctx.Configuration.Session.Inactivity = 10
|
|
||||||
|
|
||||||
userSession := mock.Ctx.GetSession()
|
userSession := mock.Ctx.GetSession()
|
||||||
userSession.Username = "john"
|
userSession.Username = "john"
|
||||||
|
@ -522,8 +554,7 @@ func TestShouldKeepSessionWhenInactivityTimeoutHasNotBeenExceeded(t *testing.T)
|
||||||
clock := mocks.TestingClock{}
|
clock := mocks.TestingClock{}
|
||||||
clock.Set(time.Now())
|
clock.Set(time.Now())
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
mock.Ctx.Configuration.Session.Inactivity = "10"
|
||||||
mock.Ctx.Configuration.Session.Inactivity = 10
|
|
||||||
|
|
||||||
userSession := mock.Ctx.GetSession()
|
userSession := mock.Ctx.GetSession()
|
||||||
userSession.Username = "john"
|
userSession.Username = "john"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pquerna/otp"
|
"github.com/pquerna/otp"
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TOTPVerifier interface {
|
type TOTPVerifier interface {
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockTOTPVerifier is a mock of TOTPVerifier interface
|
// MockTOTPVerifier is a mock of TOTPVerifier interface
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MethodList is the list of available methods.
|
// MethodList is the list of available methods.
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
gomock "github.com/golang/mock/gomock"
|
||||||
u2f "github.com/tstranex/u2f"
|
u2f "github.com/tstranex/u2f"
|
||||||
reflect "reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockU2FVerifier is a mock of U2FVerifier interface
|
// MockU2FVerifier is a mock of U2FVerifier interface
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/asaskevich/govalidator"
|
"github.com/asaskevich/govalidator"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRequestLogger create a new request logger for the given request.
|
// NewRequestLogger create a new request logger for the given request.
|
||||||
|
|
|
@ -5,12 +5,13 @@ import (
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldCallNextWithAutheliaCtx(t *testing.T) {
|
func TestShouldCallNextWithAutheliaCtx(t *testing.T) {
|
||||||
|
|
|
@ -6,8 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/templates"
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentityVerificationStart the handler for initiating the identity validation process.
|
// IdentityVerificationStart the handler for initiating the identity validation process.
|
||||||
|
|
|
@ -5,13 +5,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
|
||||||
"github.com/authelia/authelia/internal/session"
|
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
|
"github.com/authelia/authelia/internal/session"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newArgs(retriever func(ctx *middlewares.AutheliaCtx) (*session.Identity, error)) middlewares.IdentityVerificationStartArgs {
|
func newArgs(retriever func(ctx *middlewares.AutheliaCtx) (*session.Identity, error)) middlewares.IdentityVerificationStartArgs {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package middlewares
|
package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
@ -9,9 +13,6 @@ import (
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
jwt "github.com/dgrijalva/jwt-go"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AutheliaCtx contains all server variables related to Authelia.
|
// AutheliaCtx contains all server variables related to Authelia.
|
||||||
|
|
|
@ -6,19 +6,21 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/regulation"
|
|
||||||
"github.com/authelia/authelia/internal/storage"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/regulation"
|
||||||
|
"github.com/authelia/authelia/internal/storage"
|
||||||
|
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/sirupsen/logrus/hooks/test"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authorization"
|
"github.com/authelia/authelia/internal/authorization"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
"github.com/authelia/authelia/internal/session"
|
"github.com/authelia/authelia/internal/session"
|
||||||
"github.com/golang/mock/gomock"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"github.com/sirupsen/logrus/hooks/test"
|
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockAutheliaCtx a mock of AutheliaCtx
|
// MockAutheliaCtx a mock of AutheliaCtx
|
||||||
|
|
|
@ -8,9 +8,10 @@ import (
|
||||||
url "net/url"
|
url "net/url"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
|
||||||
duo "github.com/authelia/authelia/internal/duo"
|
duo "github.com/authelia/authelia/internal/duo"
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockAPI is a mock of API interface
|
// MockAPI is a mock of API interface
|
||||||
|
|
|
@ -7,8 +7,9 @@ package mocks
|
||||||
import (
|
import (
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
authentication "github.com/authelia/authelia/internal/authentication"
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
|
||||||
|
authentication "github.com/authelia/authelia/internal/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockUserProvider is a mock of UserProvider interface
|
// MockUserProvider is a mock of UserProvider interface
|
||||||
|
|
|
@ -9,9 +9,10 @@ import (
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
"github.com/authelia/authelia/internal/utils"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SMTPNotifier a notifier to send emails to SMTP servers.
|
// SMTPNotifier a notifier to send emails to SMTP servers.
|
||||||
|
|
|
@ -15,14 +15,24 @@ func NewRegulator(configuration *schema.RegulationConfiguration, provider storag
|
||||||
regulator := &Regulator{storageProvider: provider}
|
regulator := &Regulator{storageProvider: provider}
|
||||||
regulator.clock = clock
|
regulator.clock = clock
|
||||||
if configuration != nil {
|
if configuration != nil {
|
||||||
if configuration.FindTime > configuration.BanTime {
|
findTime, err := utils.ParseDurationString(configuration.FindTime)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
banTime, err := utils.ParseDurationString(configuration.BanTime)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if findTime > banTime {
|
||||||
panic(fmt.Errorf("find_time cannot be greater than ban_time"))
|
panic(fmt.Errorf("find_time cannot be greater than ban_time"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set regulator enabled only if MaxRetries is not 0.
|
// Set regulator enabled only if MaxRetries is not 0.
|
||||||
regulator.enabled = configuration.MaxRetries > 0
|
regulator.enabled = configuration.MaxRetries > 0
|
||||||
regulator.maxRetries = configuration.MaxRetries
|
regulator.maxRetries = configuration.MaxRetries
|
||||||
regulator.findTime = time.Duration(configuration.FindTime) * time.Second
|
regulator.findTime = findTime
|
||||||
regulator.banTime = time.Duration(configuration.BanTime) * time.Second
|
regulator.banTime = banTime
|
||||||
}
|
}
|
||||||
return regulator
|
return regulator
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,15 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/mocks"
|
"github.com/authelia/authelia/internal/mocks"
|
||||||
"github.com/authelia/authelia/internal/models"
|
"github.com/authelia/authelia/internal/models"
|
||||||
"github.com/authelia/authelia/internal/regulation"
|
"github.com/authelia/authelia/internal/regulation"
|
||||||
"github.com/authelia/authelia/internal/storage"
|
"github.com/authelia/authelia/internal/storage"
|
||||||
"github.com/golang/mock/gomock"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RegulatorSuite struct {
|
type RegulatorSuite struct {
|
||||||
|
@ -29,8 +30,8 @@ func (s *RegulatorSuite) SetupTest() {
|
||||||
|
|
||||||
s.configuration = schema.RegulationConfiguration{
|
s.configuration = schema.RegulationConfiguration{
|
||||||
MaxRetries: 3,
|
MaxRetries: 3,
|
||||||
BanTime: 180,
|
BanTime: "180",
|
||||||
FindTime: 30,
|
FindTime: "30",
|
||||||
}
|
}
|
||||||
s.clock.Set(time.Now())
|
s.clock.Set(time.Now())
|
||||||
}
|
}
|
||||||
|
@ -282,8 +283,8 @@ func (s *RegulatorSuite) TestShouldHaveRegulatorDisabled() {
|
||||||
// Check Disabled Functionality
|
// Check Disabled Functionality
|
||||||
configuration := schema.RegulationConfiguration{
|
configuration := schema.RegulationConfiguration{
|
||||||
MaxRetries: 0,
|
MaxRetries: 0,
|
||||||
FindTime: 180,
|
FindTime: "180",
|
||||||
BanTime: 180,
|
BanTime: "180",
|
||||||
}
|
}
|
||||||
|
|
||||||
regulator := regulation.NewRegulator(&configuration, s.storageMock, &s.clock)
|
regulator := regulation.NewRegulator(&configuration, s.storageMock, &s.clock)
|
||||||
|
@ -293,8 +294,8 @@ func (s *RegulatorSuite) TestShouldHaveRegulatorDisabled() {
|
||||||
// Check Enabled Functionality
|
// Check Enabled Functionality
|
||||||
configuration = schema.RegulationConfiguration{
|
configuration = schema.RegulationConfiguration{
|
||||||
MaxRetries: 1,
|
MaxRetries: 1,
|
||||||
FindTime: 180,
|
FindTime: "180",
|
||||||
BanTime: 180,
|
BanTime: "180",
|
||||||
}
|
}
|
||||||
|
|
||||||
regulator = regulation.NewRegulator(&configuration, s.storageMock, &s.clock)
|
regulator = regulation.NewRegulator(&configuration, s.storageMock, &s.clock)
|
||||||
|
|
|
@ -5,14 +5,15 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
duoapi "github.com/duosecurity/duo_api_golang"
|
||||||
|
"github.com/fasthttp/router"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/duo"
|
"github.com/authelia/authelia/internal/duo"
|
||||||
"github.com/authelia/authelia/internal/handlers"
|
"github.com/authelia/authelia/internal/handlers"
|
||||||
"github.com/authelia/authelia/internal/logging"
|
"github.com/authelia/authelia/internal/logging"
|
||||||
"github.com/authelia/authelia/internal/middlewares"
|
"github.com/authelia/authelia/internal/middlewares"
|
||||||
duoapi "github.com/duosecurity/duo_api_golang"
|
|
||||||
"github.com/fasthttp/router"
|
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartServer start Authelia server with the given configuration and providers.
|
// StartServer start Authelia server with the given configuration and providers.
|
||||||
|
|
|
@ -4,8 +4,9 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/fasthttp/session"
|
"github.com/fasthttp/session"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncryptingSerializer a serializer encrypting the data with AES-GCM with 256-bit keys.
|
// EncryptingSerializer a serializer encrypting the data with AES-GCM with 256-bit keys.
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
package mock_session
|
package mock_session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
session "github.com/fasthttp/session"
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
time "time"
|
time "time"
|
||||||
|
|
||||||
|
session "github.com/fasthttp/session"
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockStorer is a mock of Storer interface
|
// MockStorer is a mock of Storer interface
|
||||||
|
|
|
@ -2,18 +2,20 @@ package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
fasthttpsession "github.com/fasthttp/session"
|
fasthttpsession "github.com/fasthttp/session"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider a session provider.
|
// Provider a session provider.
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
sessionHolder *fasthttpsession.Session
|
sessionHolder *fasthttpsession.Session
|
||||||
RememberMe time.Duration
|
RememberMe time.Duration
|
||||||
|
Inactivity time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProvider instantiate a session provider given a configuration.
|
// NewProvider instantiate a session provider given a configuration.
|
||||||
|
@ -22,11 +24,19 @@ func NewProvider(configuration schema.SessionConfiguration) *Provider {
|
||||||
|
|
||||||
provider := new(Provider)
|
provider := new(Provider)
|
||||||
provider.sessionHolder = fasthttpsession.New(providerConfig.config)
|
provider.sessionHolder = fasthttpsession.New(providerConfig.config)
|
||||||
|
|
||||||
duration, err := utils.ParseDurationString(configuration.RememberMeDuration)
|
duration, err := utils.ParseDurationString(configuration.RememberMeDuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
provider.RememberMe = duration
|
provider.RememberMe = duration
|
||||||
|
|
||||||
|
duration, err = utils.ParseDurationString(configuration.Inactivity)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
provider.Inactivity = duration
|
||||||
|
|
||||||
err = provider.sessionHolder.SetProvider(providerConfig.providerName, providerConfig.providerConfig)
|
err = provider.sessionHolder.SetProvider(providerConfig.providerName, providerConfig.providerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/valyala/fasthttp"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/fasthttp/session"
|
"github.com/fasthttp/session"
|
||||||
"github.com/fasthttp/session/memory"
|
"github.com/fasthttp/session/memory"
|
||||||
"github.com/fasthttp/session/redis"
|
"github.com/fasthttp/session/redis"
|
||||||
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewProviderConfig creates a configuration for creating the session provider
|
// NewProviderConfig creates a configuration for creating the session provider
|
||||||
|
@ -24,13 +23,8 @@ func NewProviderConfig(configuration schema.SessionConfiguration) ProviderConfig
|
||||||
// Only serve the header over HTTPS.
|
// Only serve the header over HTTPS.
|
||||||
config.Secure = true
|
config.Secure = true
|
||||||
|
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
// Ignore the error as it will be handled by validator
|
||||||
if configuration.Expiration > 0 {
|
config.Expires, _ = utils.ParseDurationString(configuration.Expiration)
|
||||||
config.Expires = time.Duration(configuration.Expiration) * time.Second
|
|
||||||
} else {
|
|
||||||
// If Expiration is 0 then cookie expiration is disabled.
|
|
||||||
config.Expires = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(c.michaud): Make this configurable by giving the list of IPs that are trustable.
|
// TODO(c.michaud): Make this configurable by giving the list of IPs that are trustable.
|
||||||
config.IsSecureFunc = func(*fasthttp.RequestCtx) bool {
|
config.IsSecureFunc = func(*fasthttp.RequestCtx) bool {
|
||||||
|
|
|
@ -5,13 +5,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
"github.com/fasthttp/session"
|
"github.com/fasthttp/session"
|
||||||
"github.com/fasthttp/session/memory"
|
"github.com/fasthttp/session/memory"
|
||||||
"github.com/fasthttp/session/redis"
|
"github.com/fasthttp/session/redis"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldCreateInMemorySessionProvider(t *testing.T) {
|
func TestShouldCreateInMemorySessionProvider(t *testing.T) {
|
||||||
|
@ -19,8 +20,7 @@ func TestShouldCreateInMemorySessionProvider(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
providerConfig := NewProviderConfig(configuration)
|
providerConfig := NewProviderConfig(configuration)
|
||||||
|
|
||||||
assert.Equal(t, "my_session", providerConfig.config.CookieName)
|
assert.Equal(t, "my_session", providerConfig.config.CookieName)
|
||||||
|
@ -38,8 +38,7 @@ func TestShouldCreateRedisSessionProvider(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
configuration.Redis = &schema.RedisSessionConfiguration{
|
configuration.Redis = &schema.RedisSessionConfiguration{
|
||||||
Host: "redis.example.com",
|
Host: "redis.example.com",
|
||||||
Port: 6379,
|
Port: 6379,
|
||||||
|
@ -68,8 +67,7 @@ func TestShouldSetDbNumber(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
configuration.Redis = &schema.RedisSessionConfiguration{
|
configuration.Redis = &schema.RedisSessionConfiguration{
|
||||||
Host: "redis.example.com",
|
Host: "redis.example.com",
|
||||||
Port: 6379,
|
Port: 6379,
|
||||||
|
|
|
@ -3,13 +3,11 @@ package session
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,8 +16,7 @@ func TestShouldInitializerSession(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
|
|
||||||
provider := NewProvider(configuration)
|
provider := NewProvider(configuration)
|
||||||
session, err := provider.GetSession(ctx)
|
session, err := provider.GetSession(ctx)
|
||||||
|
@ -33,8 +30,7 @@ func TestShouldUpdateSession(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
|
|
||||||
provider := NewProvider(configuration)
|
provider := NewProvider(configuration)
|
||||||
session, _ := provider.GetSession(ctx)
|
session, _ := provider.GetSession(ctx)
|
||||||
|
@ -59,8 +55,7 @@ func TestShouldDestroySessionAndWipeSessionData(t *testing.T) {
|
||||||
configuration := schema.SessionConfiguration{}
|
configuration := schema.SessionConfiguration{}
|
||||||
configuration.Domain = "example.com"
|
configuration.Domain = "example.com"
|
||||||
configuration.Name = "my_session"
|
configuration.Name = "my_session"
|
||||||
// TODO(james-d-elliott): Convert to duration notation
|
configuration.Expiration = "40"
|
||||||
configuration.Expiration = 40
|
|
||||||
|
|
||||||
provider := NewProvider(configuration)
|
provider := NewProvider(configuration)
|
||||||
session, err := provider.GetSession(ctx)
|
session, err := provider.GetSession(ctx)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/internal/authentication"
|
|
||||||
"github.com/fasthttp/session"
|
"github.com/fasthttp/session"
|
||||||
"github.com/tstranex/u2f"
|
"github.com/tstranex/u2f"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProviderConfig is the configuration used to create the session provider.
|
// ProviderConfig is the configuration used to create the session provider.
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
_ "github.com/go-sql-driver/mysql" // Load the MySQL Driver used in the connection string.
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/logging"
|
"github.com/authelia/authelia/internal/logging"
|
||||||
_ "github.com/go-sql-driver/mysql" // Load the MySQL Driver used in the connection string.
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MySQLProvider is a MySQL provider
|
// MySQLProvider is a MySQL provider
|
||||||
|
|
|
@ -5,9 +5,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
_ "github.com/lib/pq" // Load the PostgreSQL Driver used in the connection string.
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/configuration/schema"
|
"github.com/authelia/authelia/internal/configuration/schema"
|
||||||
"github.com/authelia/authelia/internal/logging"
|
"github.com/authelia/authelia/internal/logging"
|
||||||
_ "github.com/lib/pq" // Load the PostgreSQL Driver used in the connection string.
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PostgreSQLProvider is a Postrgres provider
|
// PostgreSQLProvider is a Postrgres provider
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
models "github.com/authelia/authelia/internal/models"
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
time "time"
|
time "time"
|
||||||
|
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
|
||||||
|
models "github.com/authelia/authelia/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockProvider is a mock of Provider interface
|
// MockProvider is a mock of Provider interface
|
||||||
|
|
|
@ -4,8 +4,9 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/logging"
|
|
||||||
_ "github.com/mattn/go-sqlite3" // Load the SQLite Driver used in the connection string.
|
_ "github.com/mattn/go-sqlite3" // Load the SQLite Driver used in the connection string.
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SQLiteProvider is a sqlite3 provider
|
// SQLiteProvider is a sqlite3 provider
|
||||||
|
|
|
@ -6,8 +6,9 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DockerEnvironment represent a docker environment
|
// DockerEnvironment represent a docker environment
|
||||||
|
|
|
@ -5,8 +5,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func waitUntilServiceLogDetected(
|
func waitUntilServiceLogDetected(
|
||||||
|
|
|
@ -5,8 +5,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var kubernetesSuiteName = "Kubernetes"
|
var kubernetesSuiteName = "Kubernetes"
|
||||||
|
|
|
@ -10,9 +10,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authelia/authelia/internal/storage"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/internal/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StandaloneWebDriverSuite struct {
|
type StandaloneWebDriverSuite struct {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShouldParseDurationString(t *testing.T) {
|
func TestShouldParseDurationString(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user