package validation import ( "regexp" "time" "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" "bitbucket.org/nemt/nemt-portal-api/infra/errors" ) const ( firstNameMaxLength = 50 lastNameMaxLength = 50 emailMaxLength = 150 memberNumberValidNumberOfLetters = 3 ) const ( formModeVisit = 1 formModeRide = 2 ) func isAlphabetic(input string) bool { for _, character := range input { if !(characterIsUpperCase(character) || characterIsLowerCase(character)) { return false } } return true } func isNumeric(input string) bool { for _, character := range input { if !characterIsNumber(character) { return false } } return true } func isEmailValid(email string) bool { validEmailRegex := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") return validEmailRegex.MatchString(email) } func isMemberNumberValid(input string) bool { if len(input) < memberNumberValidNumberOfLetters { return false } if !isAlphabetic(input[:memberNumberValidNumberOfLetters]) { return false } if !isNumeric(input[memberNumberValidNumberOfLetters:]) { return false } return true } func ValidateEligibility(user *viewmodel.User) []errors.ValidationError { var result []errors.ValidationError formMode := formModeVisit // This should be red from request, not hardcoded //First name validation if len(user.First) < 1 { result = append(result, errors.ValidationError{Field: "first", Message: "First Name is required"}) } if !isAlphabetic(user.First) { result = append(result, errors.ValidationError{Field: "first", Message: "First Name contains non-alphabetic characters"}) } if len(user.First) > firstNameMaxLength { result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"}) } //Last name validation if len(user.Last) < 1 { result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"}) } if !isAlphabetic(user.Last) { result = append(result, errors.ValidationError{Field: "last", Message: "Last Name contains non-alphabetic characters"}) } if len(user.Last) > lastNameMaxLength { result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"}) } //Email validation if user.Email != nil && len(*user.Email) > 0 { if (formMode == formModeRide) && len(*user.Email) < 1 { result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"}) } if !isEmailValid(*user.Email) { result = append(result, errors.ValidationError{Field: "email", Message: "Email is invalid"}) } if len(*user.Email) > emailMaxLength { result = append(result, errors.ValidationError{Field: "email", Message: "Email is too long"}) } } else { if formMode == formModeRide { result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"}) } } //Gender validation if ((user.Gender != nil) && len(*user.Gender) < 1) || (user.Gender == nil) { result = append(result, errors.ValidationError{Field: "gender", Message: "Member Gender is required"}) } //Member type validation if (user.Type != nil && len(*user.Type) < 1) || (user.Type == nil) { result = append(result, errors.ValidationError{Field: "type", Message: "Member Type is required"}) } //Member# validation if !isMemberNumberValid(*user.Member) { result = append(result, errors.ValidationError{Field: "member", Message: "Member# is invalid"}) } //Birthdate validation if user.BirthDate == nil { result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a Birth Date"}) } else { yesterday := time.Now().Add(-1 * time.Hour * hoursInDay) if user.BirthDate.After(yesterday) { result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a valid Birth Date"}) } } //Mobile validation if formMode == formModeRide { if (user.PhoneNumber != nil && len(*user.PhoneNumber) < 1) || (user.PhoneNumber == nil) { result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Phone number is required"}) } } //User consent validation if !user.Consent { result = append(result, errors.ValidationError{Field: "consent", Message: "Must be 'Checked'"}) } return result }