Class: NotPwnedValidator
- Inherits:
-
ActiveModel::EachValidator
- Object
- ActiveModel::EachValidator
- NotPwnedValidator
- Defined in:
- lib/pwned/not_pwned_validator.rb
Overview
An ActiveModel validator to check passwords against the Pwned Passwords API.
Direct Known Subclasses
Constant Summary collapse
- DEFAULT_ON_ERROR =
The default behaviour of this validator in the case of an API failure. The default will mean that if the API fails the object will not be marked invalid.
:valid- DEFAULT_THRESHOLD =
The default threshold for whether a breach is considered pwned. The default is 0, so any password that appears in a breach will mark the record as invalid.
0
Instance Method Summary collapse
-
#validate_each(record, attribute, value) ⇒ Object
Validates the
valueagainst the Pwned Passwords API.
Instance Method Details
#validate_each(record, attribute, value) ⇒ Object
Validates the value against the Pwned Passwords API. If the pwned_count
is higher than the optional threshold then the record is marked as
invalid.
In the case of an API error the validator will either mark the record as valid or invalid. Alternatively it will run an associated proc or re-raise the original error.
The validation will short circuit and return with no errors added if the
password is blank. The Pwned::Password initializer expects the password to
be a string and will throw a TypeError if it is nil. Also, technically
the empty string is not a password that is reported to be found in data
breaches, so returns false, short circuiting that using value.blank?
saves us a trip to the API.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/pwned/not_pwned_validator.rb', line 77 def validate_each(record, attribute, value) return if value.blank? begin pwned_check = Pwned::Password.new(value, ) if pwned_check.pwned_count > threshold record.errors.add(attribute, :not_pwned, **.merge(count: pwned_check.pwned_count)) end rescue Pwned::Error => error case on_error when :invalid record.errors.add(attribute, :pwned_error, **.merge(message: [:error_message])) when :valid # Do nothing, consider the record valid when Proc on_error.call(record, error) else raise end end end |