prysm-pulse/shared/promptutil/validate.go
Ivan Martinez fc0585f724
Add promptutil to shared/promptuil (#6757)
* Add promptutil to shared/promptutil
* fixes
* comment
2020-07-29 03:04:14 +00:00

99 lines
2.5 KiB
Go

package promptutil
import (
"errors"
"strconv"
"unicode"
strongPasswords "github.com/nbutton23/zxcvbn-go"
)
const (
// Constants for passwords.
minPasswordLength = 8
// Min password score of 3 out of 5 based on the https://github.com/nbutton23/zxcvbn-go
// library for strong-entropy password computation.
minPasswordScore = 3
)
// NotEmpty is a validation function to make sure the input given isn't empty and is valid unicode.
func NotEmpty(input string) error {
if input == "" {
return errors.New("input cannot be empty")
}
if !IsValidUnicode(input) {
return errors.New("not valid unicode")
}
return nil
}
// ValidateNumber makes sure the entered text is a valid number.
func ValidateNumber(input string) error {
_, err := strconv.Atoi(input)
if err != nil {
return err
}
return nil
}
// ValidateConfirmation makes sure the entered text is the user confirming.
func ValidateConfirmation(input string) error {
if input != "Y" && input != "y" {
return errors.New("please confirm the above text")
}
return nil
}
// IsValidUnicode checks if an input string is a valid unicode string comprised of only
// letters, numbers, punctuation, or symbols.
func IsValidUnicode(input string) bool {
for _, char := range input {
if !(unicode.IsLetter(char) ||
unicode.IsNumber(char) ||
unicode.IsPunct(char) ||
unicode.IsSymbol(char)) {
return false
}
}
return true
}
// ValidatePasswordInput validates a strong password input for new accounts,
// including a min length, at least 1 number and at least
// 1 special character.
func ValidatePasswordInput(input string) error {
var (
hasMinLen = false
hasLetter = false
hasNumber = false
hasSpecial = false
)
if len(input) >= minPasswordLength {
hasMinLen = true
}
for _, char := range input {
switch {
case !(unicode.IsLetter(char) || unicode.IsNumber(char) || unicode.IsPunct(char) || unicode.IsSymbol(char)):
return errors.New("password must only contain alphanumeric characters, punctuation, or symbols")
case unicode.IsLetter(char):
hasLetter = true
case unicode.IsNumber(char):
hasNumber = true
case unicode.IsPunct(char) || unicode.IsSymbol(char):
hasSpecial = true
}
}
if !(hasMinLen && hasLetter && hasNumber && hasSpecial) {
return errors.New(
"password must have more than 8 characters, at least 1 special character, and 1 number",
)
}
strength := strongPasswords.PasswordStrength(input, nil)
if strength.Score < minPasswordScore {
return errors.New(
"password is too easy to guess, try a stronger password",
)
}
return nil
}