class PasswordStrength::Base
Constants
- GOOD
- INVALID
- MULTIPLE_NUMBERS_RE
- MULTIPLE_SYMBOLS_RE
- STRONG
- SYMBOL_RE
- UPPERCASE_LOWERCASE_RE
- WEAK
Attributes
Set what characters cannot be present on password. Can be a regular expression or array.
strength = PasswordStrength.test("john", "password with whitespaces", :exclude => [" ", "asdf"]) strength = PasswordStrength.test("john", "password with whitespaces", :exclude => /\s/)
Then you can check the test result:
strength.valid?(:weak) #=> false strength.status #=> :invalid
The password that will be tested.
The ActiveRecord instance. It only makes sense if you’re creating a custom ActiveRecord validator.
The score for the latest test. Will be nil
if the password has not been tested.
The current test status. Can be :weak
, :good
, :strong
or :invalid
.
Hold the username that will be matched against password.
Public Class Methods
Return an array of strings that represents common passwords. The default list is taken from several online sources (just Google for ‘most common passwords’).
Notable sources:
The current list has 3.6KB and its load into memory just once.
# File lib/password_strength/base.rb, line 54 def self.common_words @common_words ||= begin file = File.open(File.expand_path("../../../support/common.txt", __FILE__)) words = file.each_line.to_a.map(&:chomp) file.close words end end
# File lib/password_strength/base.rb, line 63 def initialize(username, password, options = {}) @username = username.to_s @password = password.to_s @score = 0 @exclude = options[:exclude] @record = options[:record] end
Public Instance Methods
# File lib/password_strength/base.rb, line 228 def contain_invalid_repetion? char = password.to_s.chars.first return unless char regex = /^#{Regexp.escape(char)}+$/i password.to_s =~ regex end
Mark password as good.
# File lib/password_strength/base.rb, line 110 def good! @status = GOOD end
Check if the password has been detected as good.
# File lib/password_strength/base.rb, line 105 def good? status == GOOD end
Mark password as invalid.
# File lib/password_strength/base.rb, line 120 def invalid! @status = INVALID end
Check if password has invalid characters based on PasswordStrength::Base#exclude
.
# File lib/password_strength/base.rb, line 115 def invalid? status == INVALID end
Return the score for the specified rule. Available rules:
-
:password_size
-
:numbers
-
:symbols
-
:uppercase_lowercase
-
:numbers_chars
-
:numbers_symbols
-
:symbols_chars
-
:only_chars
-
:only_numbers
-
:username
-
:sequences
# File lib/password_strength/base.rb, line 138 def score_for(name) score = 0 case name when :password_size then if password.size < 6 score = -100 else score = password.size * 4 end when :numbers then score = 5 if password =~ MULTIPLE_NUMBERS_RE when :symbols then score = 5 if password =~ MULTIPLE_SYMBOLS_RE when :uppercase_lowercase then score = 10 if password =~ UPPERCASE_LOWERCASE_RE when :numbers_chars then score = 15 if password =~ /[a-z]/i && password =~ /[0-9]/ when :numbers_symbols then score = 15 if password =~ /[0-9]/ && password =~ SYMBOL_RE when :symbols_chars then score = 15 if password =~ /[a-z]/i && password =~ SYMBOL_RE when :only_chars then score = -15 if password =~ /^[a-z]+$/i when :only_numbers then score = -15 if password =~ /^\d+$/ when :username then if password == username score = -100 else score = -15 if password =~ /#{Regexp.escape(username)}/ end when :sequences then score = -15 * sequences(password) score += -15 * sequences(password.to_s.reverse) when :repetitions then score += -(repetitions(password, 2) * 4) score += -(repetitions(password, 3) * 3) score += -(repetitions(password, 4) * 2) end score end
Mark password as strong.
# File lib/password_strength/base.rb, line 90 def strong! @status = STRONG end
Check if the password has been detected as strong.
# File lib/password_strength/base.rb, line 85 def strong? status == STRONG end
Run all tests on password and return the final score.
# File lib/password_strength/base.rb, line 183 def test @score = 0 if contain_invalid_matches? invalid! elsif common_word? invalid! elsif contain_invalid_repetion? invalid! else @score += score_for(:password_size) @score += score_for(:numbers) @score += score_for(:symbols) @score += score_for(:uppercase_lowercase) @score += score_for(:numbers_chars) @score += score_for(:numbers_symbols) @score += score_for(:symbols_chars) @score += score_for(:only_chars) @score += score_for(:only_numbers) @score += score_for(:username) @score += score_for(:sequences) @score += score_for(:repetitions) @score = 0 if score < 0 @score = 100 if score > 100 weak! if score < 35 good! if score >= 35 && score < 70 strong! if score >= 70 end score end
Check if the password has the specified score. Level can be :weak
, :good
or :strong
.
# File lib/password_strength/base.rb, line 73 def valid?(level = GOOD) case level when STRONG then strong? when GOOD then good? || strong? else !invalid? end end
Mark password as weak.
# File lib/password_strength/base.rb, line 100 def weak! @status = WEAK end
Check if the password has been detected as weak.
# File lib/password_strength/base.rb, line 95 def weak? status == WEAK end