password_strength 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  require "test_helper"
2
3
 
3
4
  class TestPasswordStrength < Test::Unit::TestCase
@@ -17,16 +18,16 @@ class TestPasswordStrength < Test::Unit::TestCase
17
18
  @strength.instance_variable_set("@status", :good)
18
19
  assert @strength.good?
19
20
  assert @strength.valid?(:good)
20
- assert_equal false, @strength.weak?
21
- assert_equal false, @strength.strong?
21
+ refute @strength.weak?
22
+ refute @strength.strong?
22
23
  end
23
24
 
24
25
  def test_weak_strength
25
26
  @strength.instance_variable_set("@status", :weak)
26
27
  assert @strength.weak?
27
28
  assert @strength.valid?(:weak)
28
- assert_equal false, @strength.good?
29
- assert_equal false, @strength.strong?
29
+ refute @strength.good?
30
+ refute @strength.strong?
30
31
  end
31
32
 
32
33
  def test_strong_strength
@@ -34,8 +35,8 @@ class TestPasswordStrength < Test::Unit::TestCase
34
35
  assert @strength.strong?
35
36
  assert @strength.valid?(:strong)
36
37
  assert @strength.valid?(:good)
37
- assert_equal false, @strength.good?
38
- assert_equal false, @strength.weak?
38
+ refute @strength.good?
39
+ refute @strength.weak?
39
40
  end
40
41
 
41
42
  def test_short_password
@@ -63,7 +64,7 @@ class TestPasswordStrength < Test::Unit::TestCase
63
64
  end
64
65
 
65
66
  def test_weak_password
66
- @strength.password = "1234567890"
67
+ @strength.password = "ytrewq"
67
68
  @strength.test
68
69
  assert_equal :weak, @strength.status
69
70
 
@@ -228,13 +229,24 @@ class TestPasswordStrength < Test::Unit::TestCase
228
229
  @strength = PasswordStrength.test("johndoe", "^Str0ng P4ssw0rd$", :exclude => /\s/)
229
230
  assert_equal :invalid, @strength.status
230
231
  assert @strength.invalid?
231
- assert_equal false, @strength.valid?
232
+ refute @strength.valid?
232
233
  end
233
234
 
234
235
  def test_exclude_option_as_array
235
236
  @strength = PasswordStrength.test("johndoe", "asdfasdfasdf", :exclude => ["asdf", "123"])
236
237
  assert_equal :invalid, @strength.status
237
238
  assert @strength.invalid?
238
- assert_equal false, @strength.valid?
239
+ refute @strength.valid?
240
+ end
241
+
242
+ def test_loads_common_words
243
+ assert PasswordStrength::Base.common_words.size > 500
244
+ end
245
+
246
+ def test_reject_common_words
247
+ @strength = PasswordStrength.test("johndoe", PasswordStrength::Base.common_words.first)
248
+ assert_equal :invalid, @strength.status
249
+ assert @strength.invalid?
250
+ refute @strength.valid?
239
251
  end
240
252
  end
data/test/test_helper.rb CHANGED
@@ -1,9 +1,10 @@
1
- $KCODE = "utf8" if RUBY_VERSION < "1.9"
2
-
1
+ require "bundler/setup"
3
2
  require "test/unit"
4
3
  require "ostruct"
5
4
  require "active_record"
6
5
 
6
+ I18n.enforce_available_locales = false
7
+
7
8
  Rails = OpenStruct.new(:version => ActiveRecord::VERSION::STRING)
8
9
  require "password_strength"
9
10
 
metadata CHANGED
@@ -1,71 +1,131 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: password_strength
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 3
9
- - 2
10
- version: 0.3.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Nando Vieira
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2010-09-17 00:00:00 -03:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: activesupport
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
11
+ date: 2014-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
27
17
  - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 9
30
- segments:
31
- - 2
32
- - 3
33
- - 5
34
- version: 2.3.5
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
35
20
  type: :runtime
36
- version_requirements: *id001
37
- description: |
38
- Validates the strength of a password according to several rules:
39
-
40
- * size
41
- * 3+ numbers
42
- * 2+ special characters
43
- * uppercased and downcased letters
44
- * combination of numbers, letters and symbols
45
- * password contains username
46
- * sequences (123, abc, aaa)
47
-
48
- email: fnando.vieira@gmail.com
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-meta
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'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Check password strength against several rules. Includes ActiveRecord
98
+ support.
99
+ email:
100
+ - fnando.vieira@gmail.com
49
101
  executables: []
50
-
51
102
  extensions: []
52
-
53
- extra_rdoc_files:
54
- - README.rdoc
55
- files:
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".travis.yml"
56
107
  - CHANGELOG.rdoc
108
+ - Gemfile
109
+ - Gemfile.lock
57
110
  - README.rdoc
58
- - javascripts/jquery.strength.js
59
- - javascripts/password_strength.js
111
+ - Rakefile
112
+ - app/assets/javascripts/jquery_strength.js
113
+ - app/assets/javascripts/password_strength.js
114
+ - gemfiles/ar_3_2.gemfile
115
+ - gemfiles/ar_4_0.gemfile
116
+ - gemfiles/ar_4_1.gemfile
60
117
  - lib/password_strength.rb
61
118
  - lib/password_strength/active_record.rb
62
119
  - lib/password_strength/active_record/ar2.rb
63
120
  - lib/password_strength/active_record/ar3.rb
64
121
  - lib/password_strength/base.rb
122
+ - lib/password_strength/engine.rb
65
123
  - lib/password_strength/validators/windows2008.rb
66
124
  - lib/password_strength/version.rb
67
125
  - locales/en.yml
68
126
  - locales/pt.yml
127
+ - password_strength.gemspec
128
+ - support/common.txt
69
129
  - test/active_record_test.rb
70
130
  - test/jquery-1.4.2.js
71
131
  - test/jquery_strength_test.html
@@ -79,42 +139,39 @@ files:
79
139
  - test/test_helper.rb
80
140
  - test/user.rb
81
141
  - test/validators/windows2008_test.rb
82
- has_rdoc: true
83
142
  homepage: http://github.com/fnando/password_strength
84
- licenses: []
85
-
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
86
146
  post_install_message:
87
- rdoc_options:
88
- - --charset=UTF-8
89
- require_paths:
147
+ rdoc_options: []
148
+ require_paths:
90
149
  - lib
91
- required_ruby_version: !ruby/object:Gem::Requirement
92
- none: false
93
- requirements:
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
94
152
  - - ">="
95
- - !ruby/object:Gem::Version
96
- hash: 3
97
- segments:
98
- - 0
99
- version: "0"
100
- required_rubygems_version: !ruby/object:Gem::Requirement
101
- none: false
102
- requirements:
153
+ - !ruby/object:Gem::Version
154
+ version: '1.9'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
103
157
  - - ">="
104
- - !ruby/object:Gem::Version
105
- hash: 3
106
- segments:
107
- - 0
108
- version: "0"
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
109
160
  requirements: []
110
-
111
161
  rubyforge_project:
112
- rubygems_version: 1.3.7
162
+ rubygems_version: 2.2.2
113
163
  signing_key:
114
- specification_version: 3
164
+ specification_version: 4
115
165
  summary: Check password strength against several rules. Includes ActiveRecord support.
116
- test_files:
166
+ test_files:
117
167
  - test/active_record_test.rb
168
+ - test/jquery-1.4.2.js
169
+ - test/jquery_strength_test.html
170
+ - test/jquery_strength_test.js
171
+ - test/jsunittest/jsunittest.js
172
+ - test/jsunittest/unittest.css
173
+ - test/password_strength_test.html
174
+ - test/password_strength_test.js
118
175
  - test/password_strength_test.rb
119
176
  - test/schema.rb
120
177
  - test/test_helper.rb
@@ -1,62 +0,0 @@
1
- (function($){
2
- $.strength = function(username, password, options, callback) {
3
- if (typeof(options) == "function") {
4
- callback = options;
5
- options = {};
6
- } else if (!options) {
7
- options = {};
8
- }
9
-
10
- var usernameField = $(username);
11
- var passwordField = $(password);
12
- var strength = new PasswordStrength();
13
-
14
- strength.exclude = options["exclude"];
15
-
16
- callback = callback || $.strength.callback;
17
-
18
- var handler = function(){
19
- strength.username = $(usernameField).val();
20
-
21
- if ($(usernameField).length == 0) {
22
- strength.username = username;
23
- }
24
-
25
- strength.password = $(passwordField).val();
26
-
27
- if ($(passwordField).length == 0) {
28
- strength.password = password;
29
- }
30
-
31
- strength.test();
32
- callback(usernameField, passwordField, strength);
33
- };
34
-
35
- $(usernameField).keydown(handler);
36
- $(usernameField).keyup(handler);
37
-
38
- $(passwordField).keydown(handler);
39
- $(passwordField).keyup(handler);
40
- };
41
-
42
- $.extend($.strength, {
43
- callback: function(username, password, strength){
44
- var img = $(password).next("img.strength");
45
-
46
- if (!img.length) {
47
- $(password).after("<img class='strength'>");
48
- img = $("img.strength");
49
- }
50
-
51
- $(img)
52
- .removeClass("weak")
53
- .removeClass("good")
54
- .removeClass("strong")
55
- .addClass(strength.status)
56
- .attr("src", $.strength[strength.status + "Image"]);
57
- },
58
- weakImage: "/images/weak.png",
59
- goodImage: "/images/good.png",
60
- strongImage: "/images/strong.png"
61
- });
62
- })(jQuery);
@@ -1,254 +0,0 @@
1
- var PasswordStrength = function() {
2
- var MULTIPLE_NUMBERS_RE = /\d.*?\d.*?\d/;
3
- var MULTIPLE_SYMBOLS_RE = /[!@#$%^&*?_~].*?[!@#$%^&*?_~]/;
4
- var UPPERCASE_LOWERCASE_RE = /([a-z].*[A-Z])|([A-Z].*[a-z])/;
5
- var SYMBOL_RE = /[!@#\$%^&*?_~]/;
6
-
7
- this.username = null;
8
- this.password = null;
9
- this.score = 0;
10
- this.status = null;
11
-
12
- this.test = function() {
13
- this.score = 0;
14
-
15
- if (this.containInvalidMatches()) {
16
- this.status = "invalid";
17
- } else {
18
- this.score += this.scoreFor("password_size");
19
- this.score += this.scoreFor("numbers");
20
- this.score += this.scoreFor("symbols");
21
- this.score += this.scoreFor("uppercase_lowercase");
22
- this.score += this.scoreFor("numbers_chars");
23
- this.score += this.scoreFor("numbers_symbols");
24
- this.score += this.scoreFor("symbols_chars");
25
- this.score += this.scoreFor("only_chars");
26
- this.score += this.scoreFor("only_numbers");
27
- this.score += this.scoreFor("username");
28
- this.score += this.scoreFor("sequences");
29
- this.score += this.scoreFor("repetitions");
30
-
31
- if (this.score < 0) {
32
- this.score = 0;
33
- }
34
-
35
- if (this.score > 100) {
36
- this.score = 100;
37
- }
38
-
39
- if (this.score < 35) {
40
- this.status = "weak";
41
- }
42
-
43
- if (this.score >= 35 && this.score < 70) {
44
- this.status = "good";
45
- }
46
-
47
- if (this.score >= 70) {
48
- this.status = "strong";
49
- }
50
- }
51
-
52
- return this.score;
53
- };
54
-
55
- this.scoreFor = function(name) {
56
- score = 0;
57
-
58
- switch (name) {
59
- case "password_size":
60
- if (this.password.length < 4) {
61
- score = -100;
62
- } else {
63
- score = this.password.length * 4;
64
- }
65
- break;
66
-
67
- case "numbers":
68
- if (this.password.match(MULTIPLE_NUMBERS_RE)) {
69
- score = 5;
70
- }
71
- break;
72
-
73
- case "symbols":
74
- if (this.password.match(MULTIPLE_SYMBOLS_RE)) {
75
- score = 5;
76
- }
77
- break;
78
-
79
- case "uppercase_lowercase":
80
- if (this.password.match(UPPERCASE_LOWERCASE_RE)) {
81
- score = 10;
82
- }
83
- break;
84
-
85
- case "numbers_chars":
86
- if (this.password.match(/[a-z]/i) && this.password.match(/[0-9]/)) {
87
- score = 15;
88
- }
89
- break;
90
-
91
- case "numbers_symbols":
92
- if (this.password.match(/[0-9]/) && this.password.match(SYMBOL_RE)) {
93
- score = 15;
94
- }
95
- break;
96
-
97
- case "symbols_chars":
98
- if (this.password.match(/[a-z]/i) && this.password.match(SYMBOL_RE)) {
99
- score = 15;
100
- }
101
- break;
102
-
103
- case "only_chars":
104
- if (this.password.match(/^[a-z]+$/i)) {
105
- score = -15;
106
- }
107
- break;
108
-
109
- case "only_numbers":
110
- if (this.password.match(/^\d+$/i)) {
111
- score = -15;
112
- }
113
- break;
114
-
115
- case "username":
116
- if (this.password == this.username) {
117
- score = -100;
118
- } else if (this.password.indexOf(this.username) != -1) {
119
- score = -15;
120
- }
121
- break;
122
-
123
- case "sequences":
124
- score += -15 * this.sequences(this.password);
125
- score += -15 * this.sequences(this.reversed(this.password));
126
- break;
127
-
128
- case "repetitions":
129
- score += -(this.repetitions(this.password, 2) * 4);
130
- score += -(this.repetitions(this.password, 3) * 3);
131
- score += -(this.repetitions(this.password, 4) * 2);
132
- break;
133
- };
134
-
135
- return score;
136
- };
137
-
138
- this.isGood = function() {
139
- return this.status == "good";
140
- };
141
-
142
- this.isWeak = function() {
143
- return this.status == "weak";
144
- };
145
-
146
- this.isStrong = function() {
147
- return this.status == "strong";
148
- };
149
-
150
- this.isInvalid = function() {
151
- return this.status == "invalid";
152
- };
153
-
154
- this.isValid = function(level) {
155
- if(level == "strong") {
156
- return this.isStrong();
157
- } else if (level == "good") {
158
- return this.isStrong() || this.isGood();
159
- } else {
160
- return !this.containInvalidMatches();
161
- }
162
- };
163
-
164
- this.containInvalidMatches = function() {
165
- if (!this.exclude) {
166
- return false;
167
- }
168
-
169
- if (!this.exclude.test) {
170
- return false;
171
- }
172
-
173
- return this.exclude.test(this.password.toString());
174
- };
175
-
176
- this.sequences = function(text) {
177
- var matches = 0;
178
- var sequenceSize = 0;
179
- var codes = [];
180
- var len = text.length;
181
- var previousCode, currentCode;
182
-
183
- for (var i = 0; i < len; i++) {
184
- currentCode = text.charCodeAt(i);
185
- previousCode = codes[codes.length - 1];
186
- codes.push(currentCode);
187
-
188
- if (previousCode) {
189
- if (currentCode == previousCode + 1 || previousCode == currentCode) {
190
- sequenceSize += 1;
191
- } else {
192
- sequenceSize = 0;
193
- }
194
- }
195
-
196
- if (sequenceSize == 2) {
197
- matches += 1;
198
- }
199
- }
200
-
201
- return matches;
202
- };
203
-
204
- this.repetitions = function(text, size) {
205
- var count = 0;
206
- var matches = {};
207
- var len = text.length;
208
- var substring;
209
- var occurrences;
210
- var tmpText;
211
-
212
- for (var i = 0; i < len; i++) {
213
- substring = text.substr(i, size);
214
- occurrences = 0;
215
- tmpText = text;
216
-
217
- if (matches[substring] || substring.length < size) {
218
- continue;
219
- }
220
-
221
- matches[substring] = true;
222
-
223
- while ((i = tmpText.indexOf(substring)) != -1) {
224
- occurrences += 1;
225
- tmpText = tmpText.substr(i + 1);
226
- };
227
-
228
- if (occurrences > 1) {
229
- count += 1;
230
- }
231
- }
232
-
233
- return count;
234
- };
235
-
236
- this.reversed = function(text) {
237
- var newText = "";
238
- var len = text.length;
239
-
240
- for (var i = len -1; i >= 0; i--) {
241
- newText += text.charAt(i);
242
- }
243
-
244
- return newText;
245
- };
246
- };
247
-
248
- PasswordStrength.test = function(username, password) {
249
- strength = new PasswordStrength();
250
- strength.username = username;
251
- strength.password = password;
252
- strength.test();
253
- return strength;
254
- };