Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
90
cloud/maplepress-backend/pkg/security/password/validator.go
Normal file
90
cloud/maplepress-backend/pkg/security/password/validator.go
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
package password
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
// MinPasswordLength is the minimum required password length
|
||||
MinPasswordLength = 8
|
||||
// MaxPasswordLength is the maximum allowed password length
|
||||
MaxPasswordLength = 128
|
||||
)
|
||||
|
||||
var (
|
||||
// Special characters allowed in passwords
|
||||
specialCharRegex = regexp.MustCompile(`[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]`)
|
||||
)
|
||||
|
||||
// PasswordValidator provides password strength validation
|
||||
type PasswordValidator interface {
|
||||
ValidatePasswordStrength(password string) error
|
||||
}
|
||||
|
||||
type passwordValidator struct{}
|
||||
|
||||
// NewPasswordValidator creates a new password validator
|
||||
func NewPasswordValidator() PasswordValidator {
|
||||
return &passwordValidator{}
|
||||
}
|
||||
|
||||
// ValidatePasswordStrength validates that a password meets strength requirements
|
||||
// Requirements:
|
||||
// - At least 8 characters long
|
||||
// - At most 128 characters long
|
||||
// - Contains at least one uppercase letter
|
||||
// - Contains at least one lowercase letter
|
||||
// - Contains at least one digit
|
||||
// - Contains at least one special character
|
||||
//
|
||||
// CWE-521: Returns granular error messages to help users create strong passwords
|
||||
func (v *passwordValidator) ValidatePasswordStrength(password string) error {
|
||||
// Check length first
|
||||
if len(password) < MinPasswordLength {
|
||||
return ErrPasswordTooShort
|
||||
}
|
||||
|
||||
if len(password) > MaxPasswordLength {
|
||||
return ErrPasswordTooLong
|
||||
}
|
||||
|
||||
// Check character type requirements
|
||||
var (
|
||||
hasUpper bool
|
||||
hasLower bool
|
||||
hasNumber bool
|
||||
hasSpecial bool
|
||||
)
|
||||
|
||||
for _, char := range password {
|
||||
switch {
|
||||
case unicode.IsUpper(char):
|
||||
hasUpper = true
|
||||
case unicode.IsLower(char):
|
||||
hasLower = true
|
||||
case unicode.IsNumber(char):
|
||||
hasNumber = true
|
||||
}
|
||||
}
|
||||
|
||||
// Check for special characters
|
||||
hasSpecial = specialCharRegex.MatchString(password)
|
||||
|
||||
// Return granular error for the first missing requirement
|
||||
// This provides specific feedback to users about what's missing
|
||||
if !hasUpper {
|
||||
return ErrPasswordNoUppercase
|
||||
}
|
||||
if !hasLower {
|
||||
return ErrPasswordNoLowercase
|
||||
}
|
||||
if !hasNumber {
|
||||
return ErrPasswordNoNumber
|
||||
}
|
||||
if !hasSpecial {
|
||||
return ErrPasswordNoSpecialChar
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue