diff options
author | guillep2k <18600385+guillep2k@users.noreply.github.com> | 2019-11-19 19:44:58 -0300 |
---|---|---|
committer | zeripath <art27@cantab.net> | 2019-11-19 22:44:58 +0000 |
commit | c57edb6c7b5066da2b0f526e6ab9f7842fd785fb (patch) | |
tree | 68d44a4dbc58f8ade1373eb30fe850410511ce43 /modules/password | |
parent | eb0359cad4b725553c8bca3e95ada9c789c5da0b (diff) | |
download | gitea-c57edb6c7b5066da2b0f526e6ab9f7842fd785fb.tar.gz gitea-c57edb6c7b5066da2b0f526e6ab9f7842fd785fb.zip |
Add password requirement info on error (#9074)
* Add password requirement info on error
* Move BuildComplexityError to the password pkg
* Unexport complexity type
* Fix extra line
* Update modules/password/password.go
Co-Authored-By: Lauris BH <lauris@nix.lv>
Diffstat (limited to 'modules/password')
-rw-r--r-- | modules/password/password.go | 66 | ||||
-rw-r--r-- | modules/password/password_test.go | 4 |
2 files changed, 53 insertions, 17 deletions
diff --git a/modules/password/password.go b/modules/password/password.go index 92986977ec..1c4b9c514a 100644 --- a/modules/password/password.go +++ b/modules/password/password.go @@ -5,24 +5,44 @@ package password import ( + "bytes" "crypto/rand" "math/big" "strings" "sync" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" ) +// complexity contains information about a particular kind of password complexity +type complexity struct { + ValidChars string + TrNameOne string +} + var ( matchComplexityOnce sync.Once validChars string - requiredChars []string + requiredList []complexity - charComplexities = map[string]string{ - "lower": `abcdefghijklmnopqrstuvwxyz`, - "upper": `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, - "digit": `0123456789`, - "spec": ` !"#$%&'()*+,-./:;<=>?@[\]^_{|}~` + "`", + charComplexities = map[string]complexity{ + "lower": { + `abcdefghijklmnopqrstuvwxyz`, + "form.password_lowercase_one", + }, + "upper": { + `ABCDEFGHIJKLMNOPQRSTUVWXYZ`, + "form.password_uppercase_one", + }, + "digit": { + `0123456789`, + "form.password_digit_one", + }, + "spec": { + ` !"#$%&'()*+,-./:;<=>?@[\]^_{|}~` + "`", + "form.password_special_one", + }, } ) @@ -36,22 +56,22 @@ func NewComplexity() { func setupComplexity(values []string) { if len(values) != 1 || values[0] != "off" { for _, val := range values { - if chars, ok := charComplexities[val]; ok { - validChars += chars - requiredChars = append(requiredChars, chars) + if complex, ok := charComplexities[val]; ok { + validChars += complex.ValidChars + requiredList = append(requiredList, complex) } } - if len(requiredChars) == 0 { + if len(requiredList) == 0 { // No valid character classes found; use all classes as default - for _, chars := range charComplexities { - validChars += chars - requiredChars = append(requiredChars, chars) + for _, complex := range charComplexities { + validChars += complex.ValidChars + requiredList = append(requiredList, complex) } } } if validChars == "" { // No complexities to check; provide a sensible default for password generation - validChars = charComplexities["lower"] + charComplexities["upper"] + charComplexities["digit"] + validChars = charComplexities["lower"].ValidChars + charComplexities["upper"].ValidChars + charComplexities["digit"].ValidChars } } @@ -59,8 +79,8 @@ func setupComplexity(values []string) { func IsComplexEnough(pwd string) bool { NewComplexity() if len(validChars) > 0 { - for _, req := range requiredChars { - if !strings.ContainsAny(req, pwd) { + for _, req := range requiredList { + if !strings.ContainsAny(req.ValidChars, pwd) { return false } } @@ -86,3 +106,17 @@ func Generate(n int) (string, error) { } } } + +// BuildComplexityError builds the error message when password complexity checks fail +func BuildComplexityError(ctx *context.Context) string { + var buffer bytes.Buffer + buffer.WriteString(ctx.Tr("form.password_complexity")) + buffer.WriteString("<ul>") + for _, c := range requiredList { + buffer.WriteString("<li>") + buffer.WriteString(ctx.Tr(c.TrNameOne)) + buffer.WriteString("</li>") + } + buffer.WriteString("</ul>") + return buffer.String() +} diff --git a/modules/password/password_test.go b/modules/password/password_test.go index d46a6d1571..4325086b50 100644 --- a/modules/password/password_test.go +++ b/modules/password/password_test.go @@ -18,6 +18,7 @@ func TestComplexity_IsComplexEnough(t *testing.T) { truevalues []string falsevalues []string }{ + {[]string{"off"}, []string{"1", "-", "a", "A", "ñ", "日本語"}, []string{}}, {[]string{"lower"}, []string{"abc", "abc!"}, []string{"ABC", "123", "=!$", ""}}, {[]string{"upper"}, []string{"ABC"}, []string{"abc", "123", "=!$", "abc!", ""}}, {[]string{"digit"}, []string{"123"}, []string{"abc", "ABC", "=!$", "abc!", ""}}, @@ -25,6 +26,7 @@ func TestComplexity_IsComplexEnough(t *testing.T) { {[]string{"off"}, []string{"abc", "ABC", "123", "=!$", "abc!", ""}, nil}, {[]string{"lower", "spec"}, []string{"abc!"}, []string{"abc", "ABC", "123", "=!$", "abcABC123", ""}}, {[]string{"lower", "upper", "digit"}, []string{"abcABC123"}, []string{"abc", "ABC", "123", "=!$", "abc!", ""}}, + {[]string{""}, []string{"abC=1", "abc!9D"}, []string{"ABC", "123", "=!$", ""}}, } for _, test := range testlist { @@ -70,6 +72,6 @@ func TestComplexity_Generate(t *testing.T) { func testComplextity(values []string) { // Cleanup previous values validChars = "" - requiredChars = make([]string, 0, len(values)) + requiredList = make([]complexity, 0, len(values)) setupComplexity(values) } |