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  }