-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
password.go
65 lines (52 loc) · 1.72 KB
/
password.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package utils
import (
"fmt"
"regexp"
"strings"
"github.com/pkg/errors"
)
// PasswordComplexityRequirements defines the complexity requirements message
// Note that adding an entropy requirement wouldn't add much, since a 16
// character password already has an entropy score of 75 even if it's all
// lowercase characters
const PasswordComplexityRequirements = `
Must have a length of 16-50 characters
Must not comprise:
Leading or trailing whitespace (note that a trailing newline in the password file, if present, will be ignored)
`
const MinRequiredLen = 16
var LeadingWhitespace = regexp.MustCompile(`^\s+`)
var TrailingWhitespace = regexp.MustCompile(`\s+$`)
var (
ErrMsgHeader = fmt.Sprintf(`
Expected password complexity:
Must be at least %d characters long
Must not comprise:
Leading or trailing whitespace
A user's API email
Faults:
`, MinRequiredLen)
ErrWhitespace = errors.New("password contains a leading or trailing whitespace")
)
func VerifyPasswordComplexity(password string, disallowedStrings ...string) (merr error) {
errMsg := ErrMsgHeader
var stringErrs []string
if LeadingWhitespace.MatchString(password) || TrailingWhitespace.MatchString(password) {
stringErrs = append(stringErrs, ErrWhitespace.Error())
}
if len(password) < MinRequiredLen {
stringErrs = append(stringErrs, fmt.Sprintf("password is %d characters long", len(password)))
}
for _, s := range disallowedStrings {
if strings.Contains(strings.ToLower(password), strings.ToLower(s)) {
stringErrs = append(stringErrs, fmt.Sprintf("password may not contain: %q", s))
}
}
if len(stringErrs) > 0 {
for _, stringErr := range stringErrs {
errMsg = fmt.Sprintf("%s %s\n", errMsg, stringErr)
}
merr = errors.New(errMsg)
}
return
}