strong_password 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2096a893ba8dd706abcd55dca27bef4595757b44
4
- data.tar.gz: 3223d986cc149971258c53a9bf4bc85a49cf13ff
3
+ metadata.gz: 21042c15094f1a9a0f960b16435fee882ac7e517
4
+ data.tar.gz: f4e9cf9c311aa13a7cf591b866d1f43a91c91290
5
5
  SHA512:
6
- metadata.gz: 6670c0fa8982bee8acaec5fda404560ab55860fe76ccbe369e4a048297035e625a1040c6699c138d444f62cf3d6cb2d7eaf382b7154f0d7e490c5295ce331509
7
- data.tar.gz: 0dab918c62d3fb5e39996878a67ae61a7a6275ffd141f8a7f700d9685ea1aed6a07a02cb34c168131149ec73f72a7fc0630be152a699a0dd1bc02b477bb13221
6
+ metadata.gz: b5be352df9e03643ab21a4c10ba1bdc9561607776faa8974ea59563b43432cfc62a6824d86365811875672a57028c99887df4aee172618f5c0c407d2312ed974
7
+ data.tar.gz: 67032a9ff38562e8893a9dbd581d55a79531a9b83165029bdbcf05fcf883ab4effd8a8021996c79167fc3d8fc1193d25bfda9b71b2e894c4a31a4a264d244806
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ - 2.1.7
5
+ - ruby-head
6
+ env:
7
+ - "RAILS_VERSION=4.2"
8
+ - "RAILS_VERSION=4.1"
9
+ - "RAILS_VERSION=4.0"
10
+ - "RAILS_VERSION=3.2"
11
+ - "RAILS_VERSION=3.1"
12
+ - "RAILS_VERSION=3.0"
13
+ - "RAILS_VERSION=master"
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: ruby-head
17
+ - env: "RAILS_VERSION=master"
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- version = ENV["RAILS_VERSION"] || "3.2"
5
+ version = ENV["RAILS_VERSION"] || "4.2"
6
6
 
7
7
  rails = case version
8
8
  when "master"
@@ -11,4 +11,5 @@ else
11
11
  "~> #{version}.0"
12
12
  end
13
13
 
14
- gem "rails", rails
14
+ gem "rails", rails
15
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ [![Build Status](https://travis-ci.org/bdmac/strong_password.svg?branch=master)](https://travis-ci.org/bdmac/strong_password)
2
+ [![Code Climate](https://codeclimate.com/github/bdmac/strong_password/badges/gpa.svg)](https://codeclimate.com/github/bdmac/strong_password)
3
+ [![Test Coverage](https://codeclimate.com/github/bdmac/strong_password/badges/coverage.svg)](https://codeclimate.com/github/bdmac/strong_password/coverage)
4
+
1
5
  # StrongPassword
2
6
 
3
7
  StrongPassword provides entropy-based password strength checking for your apps.
@@ -15,7 +19,7 @@ NOTE: StrongPassword requires the use of Ruby 2.0. Upgrade if you haven't alrea
15
19
 
16
20
  Add this line to your application's Gemfile:
17
21
 
18
- gem 'strong_password', '~> 0.0.3'
22
+ gem 'strong_password', '~> 0.0.5'
19
23
 
20
24
  And then execute:
21
25
 
@@ -61,15 +65,15 @@ class User
61
65
  end
62
66
  ```
63
67
 
64
- The default validation message is "%{attribute} is too weak". If you would like to customize that you can override it in your locale file
65
- by setting a value for this key:
68
+ The default validation message is "is too weak". Rails will display a field of `:password` having too weak of a password with `full_error_messages` as "Password is too weak". If you would like to customize the error message, you can override it in your locale file by setting a value for this key:
69
+
66
70
 
67
71
  ```yml
68
72
  en:
69
73
  errors:
70
74
  messages:
71
75
  password:
72
- password_strength: "%{attribute} is a terrible password, try again!"
76
+ password_strength: "is a terrible password, try again!"
73
77
  ```
74
78
 
75
79
  ### Standalone
@@ -148,10 +152,16 @@ disallowed by the strength checker.
148
152
  dictionary of the English language but not so much when you're only talking about the 500 most
149
153
  common passwords.
150
154
 
155
+ ## Running the tests
156
+
157
+ To run the tests, install the gems with `bundle install`. Then run `rake`.
158
+
151
159
  ## Contributing
152
160
 
153
161
  1. Fork it
154
162
  2. Create your feature branch (`git checkout -b my-new-feature`)
155
- 3. Commit your changes (`git commit -am 'Add some feature'`)
156
- 4. Push to the branch (`git push origin my-new-feature`)
157
- 5. Create new Pull Request
163
+ 3. Make your changes
164
+ 4. Test the changes and make sure existing tests pass
165
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
166
+ 6. Push to the branch (`git push origin my-new-feature`)
167
+ 7. Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -1,4 +1,4 @@
1
- require 'active_model/validations'
1
+ require 'active_model/validations' if defined?(ActiveModel)
2
2
 
3
3
  require 'strong_password/version'
4
4
  require 'strong_password/nist_bonus_bits'
@@ -12,4 +12,4 @@ require 'active_model/validations/password_strength_validator' if defined?(Activ
12
12
  module StrongPassword
13
13
  end
14
14
 
15
- I18n.load_path << File.dirname(__FILE__) + '/strong_password/locale/en.yml' if defined?(I18n)
15
+ I18n.load_path << File.dirname(__FILE__) + '/strong_password/locale/en.yml' if defined?(I18n)
@@ -2,4 +2,4 @@ en:
2
2
  errors:
3
3
  messages:
4
4
  password:
5
- password_strength: "%{attribute} is too weak"
5
+ password_strength: "is too weak"
@@ -1,6 +1,8 @@
1
1
  module StrongPassword
2
2
  module PasswordVariants
3
- LEET_SPEAK_1 = {
3
+ LEET_SPEAK_REGEXP = /[\@\!\$1234567890]/
4
+
5
+ LEET_SPEAK = {
4
6
  "@" => "a",
5
7
  "!" => "i",
6
8
  "$" => "s",
@@ -16,37 +18,9 @@ module StrongPassword
16
18
  "0" => "o"
17
19
  }
18
20
 
19
- LEET_SPEAK_2 = {
20
- "@" => "a",
21
- "!" => "i",
22
- "$" => "s",
23
- "1" => "l",
24
- "2" => "z",
25
- "3" => "e",
26
- "4" => "a",
27
- "5" => "s",
28
- "6" => "g",
29
- "7" => "t",
30
- "8" => "b",
31
- "9" => "g",
32
- "0" => "o"
33
- }
21
+ LEET_SPEAK_ALT = LEET_SPEAK.dup.merge!("1" => "l")
34
22
 
35
- KEYBOARDMAP_DOWN_NOSHIFT = {
36
- "z" => "",
37
- "x" => "",
38
- "c" => "",
39
- "v" => "",
40
- "b" => "",
41
- "n" => "",
42
- "m" => "",
43
- "," => "",
44
- "." => "",
45
- "/" => "",
46
- "<" => "",
47
- ">" => "",
48
- "?" => ""
49
- }
23
+ BOTTOM_ROW_REGEXP = /[zxcvbnm,\.\/\<\>\?]/
50
24
 
51
25
  KEYBOARDMAP_DOWNRIGHT = {
52
26
  "a" => "z",
@@ -105,7 +79,7 @@ module StrongPassword
105
79
  "p" => "l",
106
80
  "-" => "p"
107
81
  }
108
-
82
+
109
83
  # Returns all variants of a given password including the password itself
110
84
  def self.all_variants(password)
111
85
  passwords = [password.downcase]
@@ -117,37 +91,26 @@ module StrongPassword
117
91
  # Returns all keyboard shifted variants of a given password
118
92
  def self.keyboard_shift_variants(password)
119
93
  password = password.downcase
120
- variants = []
121
-
122
- if (password == password.tr(KEYBOARDMAP_DOWN_NOSHIFT.keys.join, KEYBOARDMAP_DOWN_NOSHIFT.values.join))
123
- variant = password.tr(KEYBOARDMAP_DOWNRIGHT.keys.join, KEYBOARDMAP_DOWNRIGHT.values.join)
124
- variants << variant
125
- variants << variant.reverse
126
94
 
127
- variant = password.tr(KEYBOARDMAP_DOWNLEFT.keys.join, KEYBOARDMAP_DOWNLEFT.values.join)
128
- variants << variant
129
- variants << variant.reverse
130
- end
131
- variants
95
+ return [] if password.match(BOTTOM_ROW_REGEXP)
96
+ variants(password, KEYBOARDMAP_DOWNRIGHT, KEYBOARDMAP_DOWNLEFT)
132
97
  end
133
98
 
134
99
  # Returns all leet speak variants of a given password
135
100
  def self.leet_speak_variants(password)
136
101
  password = password.downcase
137
- variants = []
138
102
 
139
- leet = password.tr(LEET_SPEAK_1.keys.join, LEET_SPEAK_1.values.join)
140
- if leet != password
141
- variants << leet
142
- variants << leet.reverse
143
- end
103
+ return [] if !password.match(LEET_SPEAK_REGEXP)
104
+ variants(password, LEET_SPEAK, LEET_SPEAK_ALT)
105
+ end
106
+
107
+ private
144
108
 
145
- leet_l = password.tr(LEET_SPEAK_2.keys.join, LEET_SPEAK_2.values.join)
146
- if (leet_l != password && leet_l != leet)
147
- variants << leet_l
148
- variants << leet_l.reverse
109
+ def self.variants(password, *mappings)
110
+ mappings.flat_map do |map|
111
+ variant = password.tr(map.keys.join, map.values.join)
112
+ [variant, variant.reverse]
149
113
  end
150
- variants
151
114
  end
152
115
  end
153
- end
116
+ end
@@ -1 +1 @@
1
- require 'rails/railtie'
1
+ require 'rails/railtie' if defined?(Rails)
@@ -1,3 +1,3 @@
1
1
  module StrongPassword
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,8 +1,11 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
1
3
  require 'bundler/setup'
2
- require 'strong_password'
4
+ require 'pry'
3
5
  require 'active_model'
6
+ require 'strong_password'
4
7
 
5
8
  RSpec.configure do |config|
6
9
  config.expect_with(:rspec) {|c| c.syntax = :expect}
7
10
  config.order = :random
8
- end
11
+ end
@@ -7,12 +7,12 @@ module StrongPassword
7
7
 
8
8
  it 'returns true if the calculated entropy is >= the minimum' do
9
9
  subject.stub(adjusted_entropy: 18)
10
- expect(subject.is_strong?).to be_true
10
+ expect(subject.is_strong?).to be_truthy
11
11
  end
12
12
 
13
13
  it 'returns false if the calculated entropy is < the minimum' do
14
14
  subject.stub(adjusted_entropy: 17)
15
- expect(subject.is_strong?).to be_false
15
+ expect(subject.is_strong?).to be_falsey
16
16
  end
17
17
  end
18
18
 
@@ -21,7 +21,7 @@ module StrongPassword
21
21
 
22
22
  it 'returns the opposite of is_strong?' do
23
23
  subject.stub(is_strong?: true)
24
- expect(subject.is_weak?).to be_false
24
+ expect(subject.is_weak?).to be_falsey
25
25
  end
26
26
  end
27
27
 
@@ -52,9 +52,9 @@ module StrongPassword
52
52
  end
53
53
 
54
54
  it 'allows extra words to be provided as an array' do
55
- password = 'mcmanus'
55
+ password = 'administratorWEQ@123'
56
56
  base_entropy = EntropyCalculator.calculate(password)
57
- expect(DictionaryAdjuster.new(password).adjusted_entropy(extra_dictionary_words: ['mcmanus'])).not_to eq(base_entropy)
57
+ expect(DictionaryAdjuster.new(password).adjusted_entropy(extra_dictionary_words: ['administrator'])).not_to eq(base_entropy)
58
58
  end
59
59
 
60
60
  it 'allows minimum word length to be adjusted' do
@@ -65,4 +65,4 @@ module StrongPassword
65
65
  end
66
66
  end
67
67
  end
68
- end
68
+ end
@@ -7,24 +7,24 @@ module StrongPassword
7
7
 
8
8
  it 'returns true if the calculated entropy is >= the minimum' do
9
9
  subject.stub(adjusted_entropy: 18)
10
- expect(subject.is_strong?).to be_true
10
+ expect(subject.is_strong?).to be_truthy
11
11
  end
12
-
12
+
13
13
  it 'returns false if the calculated entropy is < the minimum' do
14
14
  subject.stub(adjusted_entropy: 17)
15
- expect(subject.is_strong?).to be_false
15
+ expect(subject.is_strong?).to be_falsey
16
16
  end
17
17
  end
18
-
18
+
19
19
  describe '#is_weak?' do
20
20
  let(:subject) { QwertyAdjuster.new('password') }
21
21
 
22
22
  it 'returns the opposite of is_strong?' do
23
23
  subject.stub(is_strong?: true)
24
- expect(subject.is_weak?).to be_false
24
+ expect(subject.is_weak?).to be_falsey
25
25
  end
26
26
  end
27
-
27
+
28
28
  describe '#adjusted_entropy' do
29
29
  before(:each) { NistBonusBits.stub(bonus_bits: 0)}
30
30
  {
@@ -42,4 +42,4 @@ module StrongPassword
42
42
  end
43
43
  end
44
44
  end
45
- end
45
+ end
@@ -18,7 +18,7 @@ class TestStrengthStrongEntropy < User
18
18
  end
19
19
 
20
20
  class TestStrengthExtraWords < User
21
- validates :password, password_strength: {extra_dictionary_words: ['mcmanus'], use_dictionary: true}
21
+ validates :password, password_strength: {extra_dictionary_words: ['administrator'], use_dictionary: true}
22
22
  end
23
23
 
24
24
  class TestBaseStrengthAlternative < User
@@ -47,7 +47,7 @@ module ActiveModel
47
47
  it "adds errors when password is '#{password}'" do
48
48
  base_strength.password = password
49
49
  base_strength.valid?
50
- expect(base_strength.errors[:password]).to eq(["Password is too weak"])
50
+ expect(base_strength.errors[:password]).to eq(["is too weak"])
51
51
  end
52
52
  end
53
53
  end
@@ -79,7 +79,7 @@ module ActiveModel
79
79
  it "adds errors when password is '#{password}'" do
80
80
  alternative_usage.password = password
81
81
  alternative_usage.valid?
82
- expect(alternative_usage.errors[:password]).to eq(["Password is too weak"])
82
+ expect(alternative_usage.errors[:password]).to eq(["is too weak"])
83
83
  end
84
84
  end
85
85
  end
@@ -129,7 +129,7 @@ module ActiveModel
129
129
  it "'#{password}' should be invalid with increased entropy requirement" do
130
130
  strong_entropy.password = password
131
131
  strong_entropy.valid?
132
- expect(strong_entropy.errors[:password]).to eq(["Password is too weak"])
132
+ expect(strong_entropy.errors[:password]).to eq(["is too weak"])
133
133
  end
134
134
  end
135
135
  end
@@ -138,14 +138,18 @@ module ActiveModel
138
138
 
139
139
  describe 'extra words' do
140
140
  it 'allows extra words to be specified as an option to the validation' do
141
- password = 'mcmanus'
141
+ password = 'administratorWEQ@123'
142
+ # Validate that without 'administrator' added to extra_dictionary_words
143
+ # this password is considered strong
142
144
  weak_entropy.password = password
143
- expect(weak_entropy.valid?).to be_true
145
+ expect(weak_entropy.valid?).to be_truthy
146
+ # Now check that with 'administrator' added to extra_dictionary_words
147
+ # in our model, the same password is considered weak.
144
148
  extra_words.password = password
145
- expect(extra_words.valid?).to be_false
149
+ expect(extra_words.valid?).to be_falsey
146
150
  end
147
151
  end
148
152
  end
149
153
  end
150
154
  end
151
- end
155
+ end
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency 'bundler', '~> 1.3'
22
22
  spec.add_development_dependency 'rake'
23
23
  spec.add_development_dependency 'rspec', '~> 2.12'
24
+ spec.add_development_dependency 'pry'
24
25
  end
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strong_password
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian McManus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-17 00:00:00.000000000 Z
11
+ date: 2016-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '2.12'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: Entropy-based password strength checking for Ruby and ActiveModel
56
70
  email:
57
71
  - bdmac97@gmail.com
@@ -59,7 +73,8 @@ executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
- - .gitignore
76
+ - ".gitignore"
77
+ - ".travis.yml"
63
78
  - CHANGELOG
64
79
  - Gemfile
65
80
  - LICENSE.txt
@@ -95,17 +110,17 @@ require_paths:
95
110
  - lib
96
111
  required_ruby_version: !ruby/object:Gem::Requirement
97
112
  requirements:
98
- - - '>='
113
+ - - ">="
99
114
  - !ruby/object:Gem::Version
100
115
  version: '0'
101
116
  required_rubygems_version: !ruby/object:Gem::Requirement
102
117
  requirements:
103
- - - '>='
118
+ - - ">="
104
119
  - !ruby/object:Gem::Version
105
120
  version: '0'
106
121
  requirements: []
107
122
  rubyforge_project:
108
- rubygems_version: 2.2.0
123
+ rubygems_version: 2.4.5
109
124
  signing_key:
110
125
  specification_version: 4
111
126
  summary: StrongPassword adds a class to check password strength and a validator for
@@ -119,3 +134,4 @@ test_files:
119
134
  - spec/strong_password/qwerty_adjuster_spec.rb
120
135
  - spec/strong_password/strength_checker_spec.rb
121
136
  - spec/validation/strength_validator_spec.rb
137
+ has_rdoc: