validate :password_complexity
def password_complexity
return if password.nil?
if password.size < 8
errors.add :password, "Must be at least 8 characters long."
return
end
required_complexity = 3 # we're actually storing this in the configuration of each customer
if !CheckPasswordComplexityService.new(password, required_complexity).valid?
errors.add :password, "Your password does not match the security requirements."
end
end
检查复杂性的服务如下所示:
class CheckPasswordComplexityService
attr_reader :password, :required_complexity
def initialize(password, required_complexity)
@password = password
@required_complexity = required_complexity
end
def valid?
score = has_uppercase_letters? + has_digits? + has_extra_chars? + has_downcase_letters?
score >= required_complexity
end
private
def has_uppercase_letters?
password.match(/[A-Z]/) ? 1 : 0
end
def has_digits?
password.match(/\d/) ? 1 : 0
end
def has_extra_chars?
password.match(/\W/) ? 1 : 0
end
def has_downcase_letters?
password.match(/[a-z]{1}/) ? 1 : 0
end
end