2024-02-16 04:58:05 -06:00
package user
import (
"unicode"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util/errutil"
)
var (
2024-02-27 10:34:43 -06:00
ErrPasswordTooShort = errutil . BadRequest ( "password.password-policy-too-short" , errutil . WithPublicMessage ( "New password is too short" ) )
ErrPasswordPolicyInfringe = errutil . BadRequest ( "password.password-policy-infringe" , errutil . WithPublicMessage ( "New password doesn't comply with the password policy" ) )
2024-02-16 04:58:05 -06:00
MinPasswordLength = 12
)
type Password string
func NewPassword ( newPassword string , config * setting . Cfg ) ( Password , error ) {
if err := ValidatePassword ( newPassword , config ) ; err != nil {
return "" , err
}
return Password ( newPassword ) , nil
}
func ( p Password ) Validate ( config * setting . Cfg ) error {
return ValidatePassword ( string ( p ) , config )
}
// ValidatePassword checks if a new password meets the required criteria based on the given configuration.
// If BasicAuthStrongPasswordPolicy is disabled, it only checks for password length.
// Otherwise, it ensures the password meets the minimum length requirement and contains at least one uppercase letter,
// one lowercase letter, one number, and one symbol.
func ValidatePassword ( newPassword string , config * setting . Cfg ) error {
if ! config . BasicAuthStrongPasswordPolicy {
if len ( newPassword ) <= 4 {
2024-02-27 10:34:43 -06:00
return ErrPasswordTooShort . Errorf ( "new password is too short" )
2024-02-16 04:58:05 -06:00
}
return nil
}
if len ( newPassword ) < MinPasswordLength {
2024-02-27 10:34:43 -06:00
return ErrPasswordPolicyInfringe . Errorf ( "new password is too short for the strong password policy" )
2024-02-16 04:58:05 -06:00
}
hasUpperCase := false
hasLowerCase := false
hasNumber := false
hasSymbol := false
for _ , r := range newPassword {
if ! hasLowerCase && unicode . IsLower ( r ) {
hasLowerCase = true
}
if ! hasUpperCase && unicode . IsUpper ( r ) {
hasUpperCase = true
}
if ! hasNumber && unicode . IsNumber ( r ) {
hasNumber = true
}
if ! hasSymbol && ! unicode . IsLetter ( r ) && ! unicode . IsNumber ( r ) {
hasSymbol = true
}
if hasUpperCase && hasLowerCase && hasNumber && hasSymbol {
return nil
}
}
2024-02-27 10:34:43 -06:00
return ErrPasswordPolicyInfringe . Errorf ( "new password doesn't comply with the password policy" )
2024-02-16 04:58:05 -06:00
}