mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
81 lines
2.3 KiB
Go
81 lines
2.3 KiB
Go
package user
|
|
|
|
import (
|
|
"unicode"
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/errutil"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
var (
|
|
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"))
|
|
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)
|
|
}
|
|
|
|
func (p Password) Hash(salt string) (Password, error) {
|
|
hashed, err := util.EncodePassword(string(p), salt)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return Password(hashed), nil
|
|
}
|
|
|
|
// 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 {
|
|
return ErrPasswordTooShort.Errorf("new password is too short")
|
|
}
|
|
return nil
|
|
}
|
|
if len(newPassword) < MinPasswordLength {
|
|
return ErrPasswordPolicyInfringe.Errorf("new password is too short for the strong password policy")
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
return ErrPasswordPolicyInfringe.Errorf("new password doesn't comply with the password policy")
|
|
}
|