module PwnedPassword::Model

The PwnedPassword module adds a new validation for Devise Models. No modifications to routes or controllers needed. Simply add :pwned_password to the list of included modules in your devise module, and all new registrations will be blocked if they use a password in this dataset haveibeenpwned.com/Passwords.

Public Instance Methods

password_pwned?(password) click to toggle source

Returns true if password is present in the PwnedPasswords dataset TODO: Implement retry behaviour described here haveibeenpwned.com/API/v2#RateLimiting

# File lib/pwned_password/model.rb, line 36
def password_pwned?(password)
  @pwned = false
  @pwned_count = 0

  options = {
    'User-Agent' => 'devise_pwned_password',
    read_timeout: self.class.pwned_password_read_timeout,
    open_timeout: self.class.pwned_password_open_timeout
  }
  pwned_password = Pwned::Password.new(password.to_s, options)
  begin
    @pwned_count = pwned_password.pwned_count
    @pwned = @pwned_count >= (persisted? ? self.class.min_password_matches_warn || self.class.min_password_matches : self.class.min_password_matches)
    return @pwned
  rescue Pwned::Error
    return false
  end

  false
end
pwned?() click to toggle source
# File lib/pwned_password/model.rb, line 26
def pwned?
  @pwned ||= false
end
pwned_count() click to toggle source
# File lib/pwned_password/model.rb, line 30
def pwned_count
  @pwned_count ||= 0
end

Private Instance Methods

not_pwned_password() click to toggle source
# File lib/pwned_password/model.rb, line 59
def not_pwned_password
  # This deliberately fails silently on 500's etc. Most apps wont want to tie the ability to sign up customers to the availability of a third party API
  if password_pwned?(password)
    errors.add(:password, :pwned)
  end
end