- Implement strict password requirements: - Minimum 8 characters - At least one uppercase letter - At least one lowercase letter - At least one number - At least one special character - Add custom validator for Echo integration - Add GetPasswordRequirements helper function - Add ValidatePassword function for manual validation
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
)
|
|
|
|
// PasswordValidator validates password complexity requirements
|
|
type PasswordValidator struct{}
|
|
|
|
// Validate checks if a password meets complexity requirements:
|
|
// - Minimum 8 characters
|
|
// - At least one uppercase letter
|
|
// - At least one lowercase letter
|
|
// - At least one number
|
|
// - At least one special character
|
|
func (v *PasswordValidator) Validate(fl validator.FieldLevel) bool {
|
|
password := fl.Field().String()
|
|
|
|
// Check minimum length
|
|
if len(password) < 8 {
|
|
return false
|
|
}
|
|
|
|
// Check for uppercase
|
|
hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)
|
|
if !hasUpper {
|
|
return false
|
|
}
|
|
|
|
// Check for lowercase
|
|
hasLower := regexp.MustCompile(`[a-z]`).MatchString(password)
|
|
if !hasLower {
|
|
return false
|
|
}
|
|
|
|
// Check for number
|
|
hasNumber := regexp.MustCompile(`[0-9]`).MatchString(password)
|
|
if !hasNumber {
|
|
return false
|
|
}
|
|
|
|
// Check for special character
|
|
hasSpecial := regexp.MustCompile(`[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]`).MatchString(password)
|
|
if !hasSpecial {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// GetPasswordRequirements returns a human-readable list of password requirements
|
|
func GetPasswordRequirements() []string {
|
|
return []string{
|
|
"At least 8 characters long",
|
|
"At least one uppercase letter (A-Z)",
|
|
"At least one lowercase letter (a-z)",
|
|
"At least one number (0-9)",
|
|
"At least one special character (!@#$%^&*()_+-=[]{}|;':\",./<>?)",
|
|
}
|
|
}
|
|
|
|
// ValidatePassword checks a password and returns an error if it doesn't meet requirements
|
|
func ValidatePassword(password string) error {
|
|
if len(password) < 8 {
|
|
return fmt.Errorf("password must be at least 8 characters long")
|
|
}
|
|
|
|
if !regexp.MustCompile(`[A-Z]`).MatchString(password) {
|
|
return fmt.Errorf("password must contain at least one uppercase letter")
|
|
}
|
|
|
|
if !regexp.MustCompile(`[a-z]`).MatchString(password) {
|
|
return fmt.Errorf("password must contain at least one lowercase letter")
|
|
}
|
|
|
|
if !regexp.MustCompile(`[0-9]`).MatchString(password) {
|
|
return fmt.Errorf("password must contain at least one number")
|
|
}
|
|
|
|
if !regexp.MustCompile(`[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]`).MatchString(password) {
|
|
return fmt.Errorf("password must contain at least one special character")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RegisterPasswordValidation registers the password validator with the validator instance
|
|
func RegisterPasswordValidation(v *validator.Validate) error {
|
|
return v.RegisterValidation("passwordcomplex", func(fl validator.FieldLevel) bool {
|
|
pv := &PasswordValidator{}
|
|
return pv.Validate(fl)
|
|
})
|
|
}
|