password_strength 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,22 @@
1
1
  = Changelog
2
2
 
3
- == March 5 2010
3
+ == 0.1.0 - March 5 2010
4
4
 
5
- * Released 0.1.0 version
5
+ * First release
6
+
7
+ == 0.1.1 - March 5 2010
8
+
9
+ * Added JavaScript implementation
10
+
11
+ == 0.1.2 - March 5 2010
12
+
13
+ * Added jQuery plugin
14
+
15
+ == 0.1.3 - March 5 2010
16
+
17
+ * Added localized error messages for +pt+ and +en+
18
+
19
+ == 0.1.4 - March 8 2010
20
+
21
+ * jQuery function can accept string instead of selectors
22
+ * Added repetition penalization
data/README.rdoc CHANGED
@@ -9,6 +9,7 @@ Validates the strength of a password according to several rules:
9
9
  * combination of numbers, letters and symbols
10
10
  * password contains username
11
11
  * sequences (123, abc, aaa)
12
+ * repetitions
12
13
 
13
14
  Some results:
14
15
 
@@ -105,7 +106,6 @@ Get the files:
105
106
 
106
107
  = TO-DO
107
108
 
108
- * Detect repetitions
109
109
  * Rake task to get the latest JavaScript file
110
110
 
111
111
  = License
@@ -1,19 +1,32 @@
1
1
  (function($){
2
2
  $.strength = function(username, password, callback) {
3
- username = $(username);
4
- password = $(password);
3
+ var usernameField = $(username);
4
+ var passwordField = $(password);
5
5
  var strength = new PasswordStrength();
6
6
  callback = callback || $.strength.callback;
7
7
 
8
8
  var handler = function(){
9
- strength.username = $(username).val();
10
- strength.password = $(this).val();
9
+ strength.username = $(usernameField).val();
10
+
11
+ if ($(usernameField).length == 0) {
12
+ strength.username = username;
13
+ }
14
+
15
+ strength.password = $(passwordField).val();
16
+
17
+ if ($(passwordField).length == 0) {
18
+ strength.password = password;
19
+ }
20
+
11
21
  strength.test();
12
- callback(username, password, strength);
22
+ callback(usernameField, passwordField, strength);
13
23
  };
14
24
 
15
- $(username).keydown(handler);
16
- $(password).keydown(handler);
25
+ $(usernameField).keydown(handler);
26
+ $(usernameField).keyup(handler);
27
+
28
+ $(passwordField).keydown(handler);
29
+ $(passwordField).keyup(handler);
17
30
  };
18
31
 
19
32
  $.extend($.strength, {
@@ -31,8 +44,6 @@
31
44
  .removeClass("strong")
32
45
  .addClass(strength.status)
33
46
  .attr("src", $.strength[strength.status + "Image"]);
34
-
35
- console.debug($.strength[strength.status + "Image"])
36
47
  },
37
48
  weakImage: "/images/weak.png",
38
49
  goodImage: "/images/good.png",
@@ -98,8 +98,12 @@ module PasswordStrength
98
98
  score = -15 if password =~ /#{Regexp.escape(username)}/
99
99
  end
100
100
  when :sequences then
101
- score = -15 * detect_sequences(password)
102
- score += -15 * detect_sequences(password.to_s.reverse)
101
+ score = -15 * sequences(password)
102
+ score += -15 * sequences(password.to_s.reverse)
103
+ when :repetitions then
104
+ score += -(repetitions(password, 2) * 4)
105
+ score += -(repetitions(password, 3) * 3)
106
+ score += -(repetitions(password, 4) * 2)
103
107
  end
104
108
 
105
109
  score
@@ -118,6 +122,7 @@ module PasswordStrength
118
122
  @score += score_for(:only_numbers)
119
123
  @score += score_for(:username)
120
124
  @score += score_for(:sequences)
125
+ @score += score_for(:repetitions)
121
126
 
122
127
  @score = 0 if score < 0
123
128
  @score = 100 if score > 100
@@ -129,7 +134,25 @@ module PasswordStrength
129
134
  score
130
135
  end
131
136
 
132
- def detect_sequences(text) # :nodoc:
137
+ def repetitions(text, size) # :nodoc:
138
+ count = 0
139
+ matches = []
140
+
141
+ 0.upto(text.size - 1) do |i|
142
+ substring = text[i, size]
143
+
144
+ next if matches.include?(substring) || substring.size < size
145
+
146
+ matches << substring
147
+ occurrences = text.scan(substring).length
148
+
149
+ count += 1 if occurrences > 1
150
+ end
151
+
152
+ count
153
+ end
154
+
155
+ def sequences(text) # :nodoc:
133
156
  matches = 0
134
157
  sequence_size = 0
135
158
  bytes = []
@@ -2,7 +2,7 @@ module PasswordStrength
2
2
  module Version # :nodoc: all
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 3
5
+ PATCH = 4
6
6
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
@@ -71,4 +71,25 @@ new Test.Unit.Runner({
71
71
  assertEqual(1, $("img.strong").length);
72
72
  assertEqual("/images/strong.png", $("img.strength").attr("src"));
73
73
  }},
74
+
75
+ // Missing username element: use selector as text
76
+ testMissingUsernameElementUseSelectorAsText: function() { with(this) {
77
+ $("#password").val("^P4ssw0rd$");
78
+ $.strength("root", "#password", function(username, password, strength){
79
+ assertEqual("root", strength.username);
80
+ assertEqual("^P4ssw0rd$", strength.password);
81
+ });
82
+
83
+ $("#password").trigger("keydown");
84
+ }},
85
+
86
+ // Missing password element: use selector as text
87
+ testMissingPasswordElementUseSelectorAsText: function() { with(this) {
88
+ $.strength("#username", "mypass", function(username, password, strength){
89
+ assertEqual("johndoe", strength.username);
90
+ assertEqual("mypass", strength.password);
91
+ });
92
+
93
+ $("#username").trigger("keydown");
94
+ }}
74
95
  });
@@ -155,6 +155,14 @@ class TestPasswordStrength < Test::Unit::TestCase
155
155
  assert_equal -100, @strength.score_for(:password_size)
156
156
  end
157
157
 
158
+ def test_penalize_repetitions
159
+ # 2-chars: ab, bc, cd, da (4 * 4 = 16)
160
+ # 3-chars: abc, bcd, cda, dab (4 * 3 = 12)
161
+ # 4-chars: abcd, bcda, cdab, dabc (4 * 2 = 8)
162
+ @strength.password = "abcdabcdabcd"
163
+ assert_equal -36, @strength.score_for(:repetitions)
164
+ end
165
+
158
166
  def test_password_length
159
167
  @strength.password = "12345"
160
168
  assert_equal 20, @strength.score_for(:password_size)
@@ -189,4 +197,19 @@ class TestPasswordStrength < Test::Unit::TestCase
189
197
  @strength.password = "a$"
190
198
  assert_equal 15, @strength.score_for(:symbols_chars)
191
199
  end
200
+
201
+ def test_two_chars_repetition
202
+ # expected: 11, 22, 12
203
+ assert_equal 3, @strength.repetitions("11221122", 2)
204
+ end
205
+
206
+ def test_three_chars_repetition
207
+ # expected: 123, 231, 312
208
+ assert_equal 3, @strength.repetitions("123123123", 3)
209
+ end
210
+
211
+ def test_four_chars_repetition
212
+ # expected: abcd, bcda, cdab, dabc
213
+ assert_equal 4, @strength.repetitions("abcdabcdabcd", 4)
214
+ end
192
215
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: password_strength
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-05 00:00:00 -03:00
12
+ date: 2010-03-08 00:00:00 -03:00
13
13
  default_executable:
14
14
  dependencies: []
15
15