Class: Philiprehberger::Password::Policy
- Inherits:
-
Object
- Object
- Philiprehberger::Password::Policy
- Defined in:
- lib/philiprehberger/password/policy.rb
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
-
#initialize(min_length: 8, max_length: 128, require_uppercase: false, require_lowercase: false, require_digit: false, require_symbol: false, reject_common: true, custom_passwords: []) ⇒ Policy
constructor
A new instance of Policy.
-
#validate(password, context: {}) ⇒ Result
Validate a password against the policy.
Constructor Details
#initialize(min_length: 8, max_length: 128, require_uppercase: false, require_lowercase: false, require_digit: false, require_symbol: false, reject_common: true, custom_passwords: []) ⇒ Policy
Returns a new instance of Policy.
8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/philiprehberger/password/policy.rb', line 8 def initialize(min_length: 8, max_length: 128, require_uppercase: false, require_lowercase: false, require_digit: false, require_symbol: false, reject_common: true, custom_passwords: []) @min_length = min_length @max_length = max_length @require_uppercase = require_uppercase @require_lowercase = require_lowercase @require_digit = require_digit @require_symbol = require_symbol @reject_common = reject_common @custom_passwords = Set.new(custom_passwords.map { |p| p.to_s.downcase }).freeze end |
Instance Method Details
#validate(password, context: {}) ⇒ Result
Validate a password against the policy. Accepts an optional context hash for context-aware validation.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/philiprehberger/password/policy.rb', line 26 def validate(password, context: {}) errors = [] return Result.new(valid?: false, errors: ['Password is required'], score: 0) if password.nil? pwd = password.to_s errors << "must be at least #{@min_length} characters" if pwd.length < @min_length errors << "must be at most #{@max_length} characters" if pwd.length > @max_length errors << 'must contain at least one uppercase letter' if @require_uppercase && !pwd.match?(/[A-Z]/) errors << 'must contain at least one lowercase letter' if @require_lowercase && !pwd.match?(/[a-z]/) errors << 'must contain at least one digit' if @require_digit && !pwd.match?(/\d/) errors << 'must contain at least one symbol' if @require_symbol && !pwd.match?(/[^a-zA-Z\d]/) errors << 'password is too common' if @reject_common && CommonPasswords.include?(pwd) if @custom_passwords.include?(pwd.downcase) && !errors.include?('password is too common') errors << 'password is too common' end # Context-aware validation errors.concat(validate_context(pwd, context)) unless context.nil? || context.empty? score = Strength.compute(pwd)[:score] Result.new(valid?: errors.empty?, errors: errors, score: score) end |