github.com/prysmaticlabs/prysm@v1.4.4/shared/promptutil/validate.go (about) 1 package promptutil 2 3 import ( 4 "errors" 5 "strconv" 6 "strings" 7 "unicode" 8 9 strongPasswords "github.com/nbutton23/zxcvbn-go" 10 ) 11 12 const ( 13 // Constants for passwords. 14 minPasswordLength = 8 15 // Min password score of 2 out of 5 based on the https://github.com/nbutton23/zxcvbn-go 16 // library for strong-entropy password computation. 17 minPasswordScore = 2 18 ) 19 20 var ( 21 errIncorrectPhrase = errors.New("input does not match wanted phrase") 22 errPasswordWeak = errors.New("password must have at least 8 characters, at least 1 alphabetical character, 1 unicode symbol, and 1 number") 23 ) 24 25 // NotEmpty is a validation function to make sure the input given isn't empty and is valid unicode. 26 func NotEmpty(input string) error { 27 if input == "" { 28 return errors.New("input cannot be empty") 29 } 30 if !IsValidUnicode(input) { 31 return errors.New("not valid unicode") 32 } 33 return nil 34 } 35 36 // ValidateNumber makes sure the entered text is a valid number. 37 func ValidateNumber(input string) error { 38 _, err := strconv.Atoi(input) 39 if err != nil { 40 return err 41 } 42 return nil 43 } 44 45 // ValidateConfirmation makes sure the entered text is the user confirming. 46 func ValidateConfirmation(input string) error { 47 if input != "Y" && input != "y" { 48 return errors.New("please confirm the above text") 49 } 50 return nil 51 } 52 53 // ValidateYesOrNo ensures the user input either Y, y or N, n. 54 func ValidateYesOrNo(input string) error { 55 lowercase := strings.ToLower(input) 56 if lowercase != "y" && lowercase != "n" { 57 return errors.New("please enter y or n") 58 } 59 return nil 60 } 61 62 // IsValidUnicode checks if an input string is a valid unicode string comprised of only 63 // letters, numbers, punctuation, or symbols. 64 func IsValidUnicode(input string) bool { 65 for _, char := range input { 66 if !(unicode.IsLetter(char) || 67 unicode.IsNumber(char) || 68 unicode.IsPunct(char) || 69 unicode.IsSymbol(char) || 70 unicode.IsSpace(char)) { 71 return false 72 } 73 } 74 return true 75 } 76 77 // ValidatePasswordInput validates a strong password input for new accounts, 78 // including a min length, at least 1 number and at least 79 // 1 special character. 80 func ValidatePasswordInput(input string) error { 81 var ( 82 hasMinLen = false 83 hasLetter = false 84 hasNumber = false 85 hasSpecial = false 86 ) 87 if len(input) >= minPasswordLength { 88 hasMinLen = true 89 } 90 for _, char := range input { 91 switch { 92 case !(unicode.IsSpace(char) || 93 unicode.IsLetter(char) || 94 unicode.IsNumber(char) || 95 unicode.IsPunct(char) || 96 unicode.IsSymbol(char)): 97 return errors.New("password must only contain unicode alphanumeric characters, numbers, or unicode symbols") 98 case unicode.IsLetter(char): 99 hasLetter = true 100 case unicode.IsNumber(char): 101 hasNumber = true 102 case unicode.IsPunct(char) || unicode.IsSymbol(char): 103 hasSpecial = true 104 } 105 } 106 if !(hasMinLen && hasLetter && hasNumber && hasSpecial) { 107 return errPasswordWeak 108 } 109 strength := strongPasswords.PasswordStrength(input, nil) 110 if strength.Score < minPasswordScore { 111 return errors.New( 112 "password is too easy to guess, try a stronger password", 113 ) 114 } 115 return nil 116 } 117 118 // ValidatePhrase checks whether the user input is equal to the wanted phrase. The verification is case sensitive. 119 func ValidatePhrase(input, wantedPhrase string) error { 120 if strings.TrimSpace(input) != wantedPhrase { 121 return errIncorrectPhrase 122 } 123 return nil 124 }