ValidatePasswordPolicy checks password against resolved config. Returns descriptive error.
(resolved *config.ResolvedConfig, password string)
| 19 | |
| 20 | // ValidatePasswordPolicy checks password against resolved config. Returns descriptive error. |
| 21 | func ValidatePasswordPolicy(resolved *config.ResolvedConfig, password string) error { |
| 22 | minLen := 8 |
| 23 | needUpper, needLower, needNum, needSpecial := true, true, true, true |
| 24 | if resolved != nil { |
| 25 | minLen = resolved.PasswordMinLength |
| 26 | needUpper = resolved.PasswordRequireUppercase |
| 27 | needLower = resolved.PasswordRequireLowercase |
| 28 | needNum = resolved.PasswordRequireNumber |
| 29 | needSpecial = resolved.PasswordRequireSpecial |
| 30 | } |
| 31 | if len(password) < minLen { |
| 32 | return fmt.Errorf("password must be at least %d characters", minLen) |
| 33 | } |
| 34 | var hasUpper, hasLower, hasNum, hasSpecial bool |
| 35 | for _, r := range password { |
| 36 | switch { |
| 37 | case unicode.IsUpper(r): |
| 38 | hasUpper = true |
| 39 | case unicode.IsLower(r): |
| 40 | hasLower = true |
| 41 | case unicode.IsNumber(r): |
| 42 | hasNum = true |
| 43 | case unicode.IsPunct(r) || unicode.IsSymbol(r): |
| 44 | hasSpecial = true |
| 45 | } |
| 46 | } |
| 47 | if needUpper && !hasUpper { |
| 48 | return fmt.Errorf("password must contain at least one uppercase letter") |
| 49 | } |
| 50 | if needLower && !hasLower { |
| 51 | return fmt.Errorf("password must contain at least one lowercase letter") |
| 52 | } |
| 53 | if needNum && !hasNum { |
| 54 | return fmt.Errorf("password must contain at least one number") |
| 55 | } |
| 56 | if needSpecial && !hasSpecial { |
| 57 | return fmt.Errorf("password must contain at least one special character") |
| 58 | } |
| 59 | return nil |
| 60 | } |
| 61 | |
| 62 | func decodeJSON(r *http.Request, v interface{}) error { |
| 63 | return json.NewDecoder(r.Body).Decode(v) |
no outgoing calls
no test coverage detected