authelia/internal/middlewares/password_policy_test.go
James Elliott 92aba8eb0b
feat(server): zxcvbn password policy server side (#3151)
This is so the zxcvbn ppolicy is checked on the server.
2022-04-15 19:30:51 +10:00

146 lines
6.0 KiB
Go

package middlewares
import (
"regexp"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/authelia/authelia/v4/internal/configuration/schema"
)
func TestNewPasswordPolicyProvider(t *testing.T) {
testCases := []struct {
desc string
have schema.PasswordPolicyConfiguration
expected PasswordPolicyProvider
}{
{
desc: "ShouldReturnUnconfiguredProvider",
have: schema.PasswordPolicyConfiguration{},
expected: &StandardPasswordPolicyProvider{},
},
{
desc: "ShouldReturnProviderWhenZxcvbn",
have: schema.PasswordPolicyConfiguration{ZXCVBN: schema.PasswordPolicyZXCVBNParams{Enabled: true, MinScore: 10}},
expected: &ZXCVBNPasswordPolicyProvider{minScore: 10},
},
{
desc: "ShouldReturnConfiguredProviderWithMin",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8}},
expected: &StandardPasswordPolicyProvider{min: 8},
},
{
desc: "ShouldReturnConfiguredProviderWitHMinMax",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, MaxLength: 100}},
expected: &StandardPasswordPolicyProvider{min: 8, max: 100},
},
{
desc: "ShouldReturnConfiguredProviderWithMinLowercase",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true}},
expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`)}},
},
{
desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercase",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}},
expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`)}},
},
{
desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercaseNumber",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireNumber: true}},
expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`), *regexp.MustCompile(`[0-9]+`)}},
},
{
desc: "ShouldReturnConfiguredProviderWithMinLowercaseUppercaseSpecial",
have: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true, RequireSpecial: true}},
expected: &StandardPasswordPolicyProvider{min: 8, patterns: []regexp.Regexp{*regexp.MustCompile(`[a-z]+`), *regexp.MustCompile(`[A-Z]+`), *regexp.MustCompile(`[^a-zA-Z0-9]+`)}},
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
actual := NewPasswordPolicyProvider(tc.have)
assert.Equal(t, tc.expected, actual)
})
}
}
func TestPasswordPolicyProvider_Validate(t *testing.T) {
testCases := []struct {
desc string
config schema.PasswordPolicyConfiguration
have []string
expected []error
}{
{
desc: "ShouldValidateAllPasswords",
config: schema.PasswordPolicyConfiguration{},
have: []string{"a", "1", "a really str0ng pass12nm3kjl12word@@#4"},
expected: []error{nil, nil, nil},
},
{
desc: "ShouldValidatePasswordMinLength",
config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8}},
have: []string{"a", "b123", "1111111", "aaaaaaaa", "1o23nm1kio2n3k12jn"},
expected: []error{errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, nil, nil},
},
{
desc: "ShouldValidatePasswordMaxLength",
config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MaxLength: 30}},
have: []string{
"a1234567894654wkjnkjasnskjandkjansdkjnas",
"012345678901234567890123456789a",
"0123456789012345678901234567890123456789",
"012345678901234567890123456789",
"1o23nm1kio2n3k12jn",
},
expected: []error{errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, nil, nil},
},
{
desc: "ShouldValidatePasswordAdvancedLowerUpperMin8",
config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, RequireLowercase: true, RequireUppercase: true}},
have: []string{"a", "b123", "1111111", "aaaaaaaa", "1o23nm1kio2n3k12jn", "ANJKJQ@#NEK!@#NJK!@#", "qjik2nkjAkjlmn123"},
expected: []error{errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, errPasswordPolicyNoMet, nil},
},
{
desc: "ShouldValidatePasswordAdvancedAllMax100Min8",
config: schema.PasswordPolicyConfiguration{Standard: schema.PasswordPolicyStandardParams{Enabled: true, MinLength: 8, MaxLength: 100, RequireLowercase: true, RequireUppercase: true, RequireNumber: true, RequireSpecial: true}},
have: []string{
"a",
"b123",
"1111111",
"aaaaaaaa",
"1o23nm1kio2n3k12jn",
"ANJKJQ@#NEK!@#NJK!@#",
"qjik2nkjAkjlmn123",
"qjik2n@jAkjlmn123",
"qjik2n@jAkjlmn123qjik2n@jAkjlmn123qjik2n@jAkjlmn123qjik2n@jAkjlmn123qjik2n@jAkjlmn123qjik2n@jAkjlmn123",
},
expected: []error{
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
errPasswordPolicyNoMet,
nil,
errPasswordPolicyNoMet,
},
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
require.Equal(t, len(tc.have), len(tc.expected))
for i := 0; i < len(tc.have); i++ {
provider := NewPasswordPolicyProvider(tc.config)
t.Run(tc.have[i], func(t *testing.T) {
assert.Equal(t, tc.expected[i], provider.Check(tc.have[i]))
})
}
})
}
}