password_strength 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,6 +22,7 @@ var PasswordStrength = function() {
22
22
  this.score += this.scoreFor("only_numbers");
23
23
  this.score += this.scoreFor("username");
24
24
  this.score += this.scoreFor("sequences");
25
+ this.score += this.scoreFor("repetitions");
25
26
 
26
27
  if (this.score < 0) {
27
28
  this.score = 0;
@@ -115,9 +116,15 @@ var PasswordStrength = function() {
115
116
  break;
116
117
 
117
118
  case "sequences":
118
- score += -15 * this.detectSequences(this.password);
119
- score += -15 * this.detectSequences(this.reversed(this.password));
120
- break
119
+ score += -15 * this.sequences(this.password);
120
+ score += -15 * this.sequences(this.reversed(this.password));
121
+ break;
122
+
123
+ case "repetitions":
124
+ score += -(this.repetitions(this.password, 2) * 4);
125
+ score += -(this.repetitions(this.password, 3) * 3);
126
+ score += -(this.repetitions(this.password, 4) * 2);
127
+ break;
121
128
  };
122
129
 
123
130
  return score;
@@ -145,7 +152,7 @@ var PasswordStrength = function() {
145
152
  }
146
153
  };
147
154
 
148
- this.detectSequences = function(text) {
155
+ this.sequences = function(text) {
149
156
  var matches = 0;
150
157
  var sequenceSize = 0;
151
158
  var codes = [];
@@ -173,6 +180,38 @@ var PasswordStrength = function() {
173
180
  return matches;
174
181
  };
175
182
 
183
+ this.repetitions = function(text, size) {
184
+ var count = 0;
185
+ var matches = {};
186
+ var len = text.length;
187
+ var substring;
188
+ var occurrences;
189
+ var tmpText;
190
+
191
+ for (var i = 0; i < len; i++) {
192
+ substring = text.substr(i, size);
193
+ occurrences = 0;
194
+ tmpText = text;
195
+
196
+ if (matches[substring] || substring.length < size) {
197
+ continue;
198
+ }
199
+
200
+ matches[substring] = true;
201
+
202
+ while ((i = tmpText.indexOf(substring)) != -1) {
203
+ occurrences += 1;
204
+ tmpText = tmpText.substr(i + 1);
205
+ };
206
+
207
+ if (occurrences > 1) {
208
+ count += 1;
209
+ }
210
+ }
211
+
212
+ return count;
213
+ };
214
+
176
215
  this.reversed = function(text) {
177
216
  var newText = "";
178
217
  var len = text.length;
@@ -1,3 +1,4 @@
1
+ require "active_support"
1
2
  require "password_strength/base"
2
3
  require "password_strength/active_record"
3
4
 
@@ -135,6 +135,7 @@ module PasswordStrength
135
135
  end
136
136
 
137
137
  def repetitions(text, size) # :nodoc:
138
+ text = text.mb_chars
138
139
  count = 0
139
140
  matches = []
140
141
 
@@ -144,8 +145,7 @@ module PasswordStrength
144
145
  next if matches.include?(substring) || substring.size < size
145
146
 
146
147
  matches << substring
147
- occurrences = text.scan(substring).length
148
-
148
+ occurrences = text.scan(/#{Regexp.escape(substring)}/).length
149
149
  count += 1 if occurrences > 1
150
150
  end
151
151
 
@@ -2,7 +2,7 @@ module PasswordStrength
2
2
  module Version # :nodoc: all
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 4
5
+ PATCH = 5
6
6
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
@@ -179,6 +179,12 @@ new Test.Unit.Runner({
179
179
  assertEqual(-100, strength.scoreFor("password_size"));
180
180
  }},
181
181
 
182
+ // Penalize repetitions
183
+ testPenalizeRepetitions: function() { with(this) {
184
+ strength.password = "abcdabcdabcd";
185
+ assertEqual(-36, strength.scoreFor("repetitions"));
186
+ }},
187
+
182
188
  // Password length
183
189
  testPasswordLength: function() { with(this) {
184
190
  strength.password = "12345";
@@ -221,5 +227,18 @@ new Test.Unit.Runner({
221
227
  assertEqual(15, strength.scoreFor("symbols_chars"));
222
228
  }},
223
229
 
230
+ // Two char repetition
231
+ testTwoCharRepetition: function() { with(this) {
232
+ assertEqual(3, strength.repetitions("11221122", 2));
233
+ }},
234
+
235
+ // Three char repetition
236
+ testThreeCharRepetition: function() { with(this) {
237
+ assertEqual(3, strength.repetitions("123123123", 3));
238
+ }},
224
239
 
240
+ // Four char repetition
241
+ testFourCharRepetition: function() { with(this) {
242
+ assertEqual(4, strength.repetitions("abcdabcdabcd", 4));
243
+ }}
225
244
  });
@@ -212,4 +212,15 @@ class TestPasswordStrength < Test::Unit::TestCase
212
212
  # expected: abcd, bcda, cdab, dabc
213
213
  assert_equal 4, @strength.repetitions("abcdabcdabcd", 4)
214
214
  end
215
+
216
+ def test_special_chars_repetition
217
+ # expected: §§, ££, §£
218
+ assert_equal 3, @strength.repetitions("§§££§§££", 2)
219
+
220
+ # expected: §£€, £€§, €§£
221
+ assert_equal 3, @strength.repetitions("§£€§£€§£€", 3)
222
+
223
+ # expected: §£€à, £€à§, €à§£, ৣ€
224
+ assert_equal 4, @strength.repetitions("§£€à§£€à§£€à", 4)
225
+ end
215
226
  end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
+ $KCODE = "utf8" if RUBY_VERSION < "1.9"
2
3
 
3
4
  require "rubygems"
4
5
  require "test/unit"
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: password_strength
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 5
9
+ version: 0.1.5
5
10
  platform: ruby
6
11
  authors:
7
12
  - Nando Vieira
@@ -9,10 +14,21 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-03-08 00:00:00 -03:00
17
+ date: 2010-03-23 00:00:00 -03:00
13
18
  default_executable:
14
- dependencies: []
15
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
16
32
  description: |
17
33
  Validates the strength of a password according to several rules:
18
34
 
@@ -69,18 +85,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
85
  requirements:
70
86
  - - ">="
71
87
  - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
72
90
  version: "0"
73
- version:
74
91
  required_rubygems_version: !ruby/object:Gem::Requirement
75
92
  requirements:
76
93
  - - ">="
77
94
  - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
78
97
  version: "0"
79
- version:
80
98
  requirements: []
81
99
 
82
100
  rubyforge_project:
83
- rubygems_version: 1.3.5
101
+ rubygems_version: 1.3.6
84
102
  signing_key:
85
103
  specification_version: 3
86
104
  summary: Check password strength against several rules. Includes ActiveRecord support.