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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb271520f8e1e9f75c210e2619ce81c63982b014
4
+ data.tar.gz: a7b360fded5d8808dc8eb7f910375b01e952cda5
5
+ SHA512:
6
+ metadata.gz: 6973d5426f558cdb89a9e57e2cee7579a3b1413d3a3f1f8b874ba25ec1fd5934c7dd9ccc3fb9806129850f521402e3f2cdf12d6bcbdd55f441abeacc6b3160a0
7
+ data.tar.gz: 8683f5d04cc022c6f0c1b49345ebc626d130a88ce6d83385abaf75ace78b8b41fcb7a3c90ce650d09afa8ecd77e8ffb9536c223ba6c066a7f13ea85ff9e2fd24
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg
2
+ coverage
3
+ doc
4
+ /gemfiles/*.lock
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ script: "bundle exec rake test"
3
+
4
+ rvm:
5
+ - 2.1.1
6
+ - 2.0.0
7
+
8
+ gemfile:
9
+ - gemfiles/ar_3_2.gemfile
10
+ - gemfiles/ar_4_0.gemfile
11
+ - gemfiles/ar_4_1.gemfile
12
+
13
+ notifications:
14
+ email:
15
+ - fnando.vieira@gmail.com
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,82 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ password_strength (0.4.0)
5
+ activerecord
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activemodel (4.0.4)
11
+ activesupport (= 4.0.4)
12
+ builder (~> 3.1.0)
13
+ activerecord (4.0.4)
14
+ activemodel (= 4.0.4)
15
+ activerecord-deprecated_finders (~> 1.0.2)
16
+ activesupport (= 4.0.4)
17
+ arel (~> 4.0.0)
18
+ activerecord-deprecated_finders (1.0.3)
19
+ activesupport (4.0.4)
20
+ i18n (~> 0.6, >= 0.6.9)
21
+ minitest (~> 4.2)
22
+ multi_json (~> 1.3)
23
+ thread_safe (~> 0.1)
24
+ tzinfo (~> 0.3.37)
25
+ arel (4.0.2)
26
+ atomic (1.1.16)
27
+ awesome_print (1.2.0)
28
+ builder (3.1.4)
29
+ coderay (1.1.0)
30
+ columnize (0.3.6)
31
+ debugger (1.6.6)
32
+ columnize (>= 0.3.1)
33
+ debugger-linecache (~> 1.2.0)
34
+ debugger-ruby_core_source (~> 1.3.2)
35
+ debugger-linecache (1.2.0)
36
+ debugger-ruby_core_source (1.3.2)
37
+ diff-lcs (1.2.5)
38
+ i18n (0.6.9)
39
+ method_source (0.8.2)
40
+ minitest (4.7.5)
41
+ multi_json (1.9.2)
42
+ pry (0.9.12.6)
43
+ coderay (~> 1.0)
44
+ method_source (~> 0.8)
45
+ slop (~> 3.4)
46
+ pry-debugger (0.2.2)
47
+ debugger (~> 1.3)
48
+ pry (~> 0.9.10)
49
+ pry-meta (0.0.6)
50
+ awesome_print
51
+ pry
52
+ pry-debugger
53
+ pry-remote
54
+ pry-remote (0.1.8)
55
+ pry (~> 0.9)
56
+ slop (~> 3.0)
57
+ rake (10.2.2)
58
+ rspec (2.14.1)
59
+ rspec-core (~> 2.14.0)
60
+ rspec-expectations (~> 2.14.0)
61
+ rspec-mocks (~> 2.14.0)
62
+ rspec-core (2.14.8)
63
+ rspec-expectations (2.14.5)
64
+ diff-lcs (>= 1.1.3, < 2.0)
65
+ rspec-mocks (2.14.6)
66
+ slop (3.5.0)
67
+ sqlite3 (1.3.9)
68
+ test-unit (2.5.5)
69
+ thread_safe (0.3.1)
70
+ atomic (>= 1.1.7, < 2)
71
+ tzinfo (0.3.39)
72
+
73
+ PLATFORMS
74
+ ruby
75
+
76
+ DEPENDENCIES
77
+ password_strength!
78
+ pry-meta
79
+ rake
80
+ rspec
81
+ sqlite3
82
+ test-unit
data/README.rdoc CHANGED
@@ -1,5 +1,7 @@
1
1
  = Introduction
2
2
 
3
+ {<img src="https://travis-ci.org/fnando/password_strength.svg" alt="Build Status" />}[https://travis-ci.org/fnando/password_strength]
4
+
3
5
  Validates the strength of a password according to several rules:
4
6
 
5
7
  * size
@@ -10,6 +12,7 @@ Validates the strength of a password according to several rules:
10
12
  * password contains username
11
13
  * sequences (123, abc, aaa)
12
14
  * repetitions
15
+ * can't be a common password (view list at support/common.txt)
13
16
 
14
17
  Some results:
15
18
 
@@ -21,7 +24,11 @@ Some results:
21
24
 
22
25
  = Install
23
26
 
24
- sudo gem install password_strength
27
+ gem install password_strength
28
+
29
+ or put this in your Gemfile:
30
+
31
+ gem "password_strength"
25
32
 
26
33
  If you want the source go to http://github.com/fnando/password_strength
27
34
 
@@ -50,7 +57,7 @@ If you want the source go to http://github.com/fnando/password_strength
50
57
 
51
58
  = ActiveRecord
52
59
 
53
- The PasswordStrength library comes with ActiveRecord support (tested on AR 2.3.5 and 3.0.0-beta).
60
+ The PasswordStrength library comes with ActiveRecord support.
54
61
 
55
62
  class Person < ActiveRecord::Base
56
63
  validates_strength_of :password
@@ -130,18 +137,22 @@ If you just want to overwrite the callback, you can simple do
130
137
 
131
138
  Get the files:
132
139
 
133
- * http://github.com/fnando/password_strength/raw/master/javascripts/password_strength.js
134
- * http://github.com/fnando/password_strength/raw/master/javascripts/jquery.strength.js
140
+ * http://github.com/fnando/password_strength/raw/master/app/assets/javascripts/password_strength.js
141
+ * http://github.com/fnando/password_strength/raw/master/app/assets/javascripts/jquery.strength.js
135
142
 
136
- = TO-DO
143
+ If you're using asset pipeline, just add the following lines to your `application.js`.
137
144
 
138
- * Rake task to get the latest JavaScript file
145
+ ```javascript
146
+ //= require jquery
147
+ //= require password_strength
148
+ //= require jquery_strength
149
+ ```
139
150
 
140
151
  = License
141
152
 
142
153
  (The MIT License)
143
154
 
144
- Copyright © 2010:
155
+ Copyright © 2010-2014:
145
156
 
146
157
  * Nando Vieira (http://simplesideias.com.br)
147
158
 
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rake/testtask"
5
+ require "rdoc/task"
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs += %w[test lib]
9
+ t.ruby_opts = %w[-rubygems]
10
+ t.test_files = FileList["test/**/*_test.rb"]
11
+ t.verbose = true
12
+ end
13
+
14
+ Rake::RDocTask.new do |rdoc|
15
+ rdoc.main = "README.rdoc"
16
+ rdoc.rdoc_dir = "doc"
17
+ rdoc.title = "Password Strength"
18
+ rdoc.options += %w[ --line-numbers --inline-source --charset utf-8 ]
19
+ rdoc.rdoc_files.include("README.rdoc", "CHANGELOG.rdoc")
20
+ rdoc.rdoc_files.include("lib/**/*.rb")
21
+ end
@@ -0,0 +1,62 @@
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);
@@ -0,0 +1,270 @@
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
+ function PasswordStrength() {
8
+ this.username = null;
9
+ this.password = null;
10
+ this.score = 0;
11
+ this.status = null;
12
+ }
13
+
14
+ PasswordStrength.fn = PasswordStrength.prototype;
15
+
16
+ PasswordStrength.fn.test = function() {
17
+ var score;
18
+ this.score = score = 0;
19
+
20
+ if (this.containInvalidMatches()) {
21
+ this.status = "invalid";
22
+ } else if (this.usesCommonWord()) {
23
+ this.status = "invalid";
24
+ } else {
25
+ score += this.scoreFor("password_size");
26
+ score += this.scoreFor("numbers");
27
+ score += this.scoreFor("symbols");
28
+ score += this.scoreFor("uppercase_lowercase");
29
+ score += this.scoreFor("numbers_chars");
30
+ score += this.scoreFor("numbers_symbols");
31
+ score += this.scoreFor("symbols_chars");
32
+ score += this.scoreFor("only_chars");
33
+ score += this.scoreFor("only_numbers");
34
+ score += this.scoreFor("username");
35
+ score += this.scoreFor("sequences");
36
+ score += this.scoreFor("repetitions");
37
+
38
+ if (score < 0) {
39
+ score = 0;
40
+ }
41
+
42
+ if (score > 100) {
43
+ score = 100;
44
+ }
45
+
46
+ if (score < 35) {
47
+ this.status = "weak";
48
+ }
49
+
50
+ if (score >= 35 && score < 70) {
51
+ this.status = "good";
52
+ }
53
+
54
+ if (score >= 70) {
55
+ this.status = "strong";
56
+ }
57
+ }
58
+
59
+ this.score = score;
60
+ return this.score;
61
+ };
62
+
63
+ PasswordStrength.fn.scoreFor = function(name) {
64
+ score = 0;
65
+
66
+ switch (name) {
67
+ case "password_size":
68
+ if (this.password.length < 4) {
69
+ score = -100;
70
+ } else {
71
+ score = this.password.length * 4;
72
+ }
73
+ break;
74
+
75
+ case "numbers":
76
+ if (this.password.match(MULTIPLE_NUMBERS_RE)) {
77
+ score = 5;
78
+ }
79
+ break;
80
+
81
+ case "symbols":
82
+ if (this.password.match(MULTIPLE_SYMBOLS_RE)) {
83
+ score = 5;
84
+ }
85
+ break;
86
+
87
+ case "uppercase_lowercase":
88
+ if (this.password.match(UPPERCASE_LOWERCASE_RE)) {
89
+ score = 10;
90
+ }
91
+ break;
92
+
93
+ case "numbers_chars":
94
+ if (this.password.match(/[a-z]/i) && this.password.match(/[0-9]/)) {
95
+ score = 15;
96
+ }
97
+ break;
98
+
99
+ case "numbers_symbols":
100
+ if (this.password.match(/[0-9]/) && this.password.match(SYMBOL_RE)) {
101
+ score = 15;
102
+ }
103
+ break;
104
+
105
+ case "symbols_chars":
106
+ if (this.password.match(/[a-z]/i) && this.password.match(SYMBOL_RE)) {
107
+ score = 15;
108
+ }
109
+ break;
110
+
111
+ case "only_chars":
112
+ if (this.password.match(/^[a-z]+$/i)) {
113
+ score = -15;
114
+ }
115
+ break;
116
+
117
+ case "only_numbers":
118
+ if (this.password.match(/^\d+$/i)) {
119
+ score = -15;
120
+ }
121
+ break;
122
+
123
+ case "username":
124
+ if (this.password == this.username) {
125
+ score = -100;
126
+ } else if (this.password.indexOf(this.username) != -1) {
127
+ score = -15;
128
+ }
129
+ break;
130
+
131
+ case "sequences":
132
+ score += -15 * this.sequences(this.password);
133
+ score += -15 * this.sequences(this.reversed(this.password));
134
+ break;
135
+
136
+ case "repetitions":
137
+ score += -(this.repetitions(this.password, 2) * 4);
138
+ score += -(this.repetitions(this.password, 3) * 3);
139
+ score += -(this.repetitions(this.password, 4) * 2);
140
+ break;
141
+ };
142
+
143
+ return score;
144
+ };
145
+
146
+ PasswordStrength.fn.isGood = function() {
147
+ return this.status == "good";
148
+ };
149
+
150
+ PasswordStrength.fn.isWeak = function() {
151
+ return this.status == "weak";
152
+ };
153
+
154
+ PasswordStrength.fn.isStrong = function() {
155
+ return this.status == "strong";
156
+ };
157
+
158
+ PasswordStrength.fn.isInvalid = function() {
159
+ return this.status == "invalid";
160
+ };
161
+
162
+ PasswordStrength.fn.isValid = function(level) {
163
+ if(level == "strong") {
164
+ return this.isStrong();
165
+ } else if (level == "good") {
166
+ return this.isStrong() || this.isGood();
167
+ } else {
168
+ return !this.containInvalidMatches();
169
+ }
170
+ };
171
+
172
+ PasswordStrength.fn.containInvalidMatches = function() {
173
+ if (!this.exclude) {
174
+ return false;
175
+ }
176
+
177
+ if (!this.exclude.test) {
178
+ return false;
179
+ }
180
+
181
+ return this.exclude.test(this.password.toString());
182
+ };
183
+
184
+ PasswordStrength.fn.usesCommonWord = function() {
185
+ return PasswordStrength.commonWords.indexOf(this.password.toLowerCase()) >= 0;
186
+ };
187
+
188
+ PasswordStrength.fn.sequences = function(text) {
189
+ var matches = 0;
190
+ var sequenceSize = 0;
191
+ var codes = [];
192
+ var len = text.length;
193
+ var previousCode, currentCode;
194
+
195
+ for (var i = 0; i < len; i++) {
196
+ currentCode = text.charCodeAt(i);
197
+ previousCode = codes[codes.length - 1];
198
+ codes.push(currentCode);
199
+
200
+ if (previousCode) {
201
+ if (currentCode == previousCode + 1 || previousCode == currentCode) {
202
+ sequenceSize += 1;
203
+ } else {
204
+ sequenceSize = 0;
205
+ }
206
+ }
207
+
208
+ if (sequenceSize == 2) {
209
+ matches += 1;
210
+ }
211
+ }
212
+
213
+ return matches;
214
+ };
215
+
216
+ PasswordStrength.fn.repetitions = function(text, size) {
217
+ var count = 0;
218
+ var matches = {};
219
+ var len = text.length;
220
+ var substring;
221
+ var occurrences;
222
+ var tmpText;
223
+
224
+ for (var i = 0; i < len; i++) {
225
+ substring = text.substr(i, size);
226
+ occurrences = 0;
227
+ tmpText = text;
228
+
229
+ if (matches[substring] || substring.length < size) {
230
+ continue;
231
+ }
232
+
233
+ matches[substring] = true;
234
+
235
+ while ((i = tmpText.indexOf(substring)) != -1) {
236
+ occurrences += 1;
237
+ tmpText = tmpText.substr(i + 1);
238
+ };
239
+
240
+ if (occurrences > 1) {
241
+ count += 1;
242
+ }
243
+ }
244
+
245
+ return count;
246
+ };
247
+
248
+ PasswordStrength.fn.reversed = function(text) {
249
+ var newText = "";
250
+ var len = text.length;
251
+
252
+ for (var i = len -1; i >= 0; i--) {
253
+ newText += text.charAt(i);
254
+ }
255
+
256
+ return newText;
257
+ };
258
+
259
+ PasswordStrength.test = function(username, password) {
260
+ strength = new PasswordStrength();
261
+ strength.username = username;
262
+ strength.password = password;
263
+ strength.test();
264
+ return strength;
265
+ };
266
+
267
+ PasswordStrength.commonWords = ["000000", "010203", "1111", "11111", "111111", "11111111", "112233", "1212", "121212", "123123", "1234", "12345", "123456", "1234567", "12345678", "123456789", "1234567890", "1313", "131313", "2000", "2112", "2222", "232323", "3333", "4128", "4321", "4444", "5150", "5555", "555555", "654321", "6666", "666666", "6969", "696969", "7777", "777777", "7777777", "8675309", "987654", "aaaa", "aaaaaa", "abc123", "abcdef", "abgrtyu", "access", "access14", "action", "admin", "adobe123", "albert", "alex", "alexis", "amanda", "amateur", "andrea", "andrew", "angel", "angela", "angels", "animal", "anthony", "apollo", "apple", "apples", "arsenal", "arthur", "asdf", "asdfgh", "ashley", "asshole", "august", "austin", "azerty", "baby", "badboy", "bailey", "banana", "barney", "baseball", "batman", "beach", "bear", "beaver", "beavis", "beer", "bigcock", "bigdaddy", "bigdick", "bigdog", "bigtits", "bill", "billy", "birdie", "bitch", "bitches", "biteme", "black", "blazer", "blonde", "blondes", "blowjob", "blowme", "blue", "bond007", "bonnie", "booboo", "boobs", "booger", "boomer", "booty", "boston", "brandon", "brandy", "braves", "brazil", "brian", "bronco", "broncos", "bubba", "buddy", "bulldog", "buster", "butter", "butthead", "calvin", "camaro", "cameron", "canada", "captain", "carlos", "carter", "casper", "charles", "charlie", "cheese", "chelsea", "chester", "chevy", "chicago", "chicken", "chris", "cocacola", "cock", "coffee", "college", "compaq", "computer", "cookie", "cool", "cooper", "corvette", "cowboy", "cowboys", "cream", "crystal", "cumming", "cumshot", "cunt", "dakota", "dallas", "daniel", "danielle", "dave", "david", "debbie", "dennis", "deuseamor", "diablo", "diamond", "dick", "dirty", "doctor", "doggie", "dolphin", "dolphins", "donald", "dragon", "dreams", "driver", "eagle", "eagle1", "eagles", "edward", "einstein", "enjoy", "enter", "eric", "erotic", "extreme", "falcon", "FaMiLia", "fender", "ferrari", "fire", "firebird", "fish", "fishing", "florida", "flower", "flyers", "football", "ford", "forever", "frank", "fred", "freddy", "freedom", "fuck", "fucked", "fucker", "fucking", "fuckme", "fuckyou", "gandalf", "gateway", "gators", "gemini", "george", "giants", "ginger", "girl", "girls", "golden", "golf", "golfer", "gordon", "great", "green", "gregory", "guitar", "gunner", "hammer", "hannah", "happy", "hardcore", "harley", "heather", "hello", "helpme", "hentai", "hockey", "hooters", "horney", "horny", "hotdog", "house", "hunter", "hunting", "iceman", "iloveyou", "internet", "iwantu", "jack", "jackie", "jackson", "jaguar", "jake", "james", "japan", "jasmine", "jason", "jasper", "jennifer", "jeremy", "jessica", "jesus", "jesuscristo", "john", "johnny", "johnson", "jordan", "joseph", "joshua", "juice", "junior", "justin", "kelly", "kevin", "killer", "king", "kitty", "knight", "ladies", "lakers", "lauren", "leather", "legend", "letmein", "little", "london", "love", "lover", "lovers", "lucky", "maddog", "madison", "maggie", "magic", "magnum", "MARCELO", "marine", "mark", "marlboro", "martin", "marvin", "master", "matrix", "matt", "matthew", "maverick", "maxwell", "melissa", "member", "mercedes", "merlin", "michael", "michelle", "mickey", "midnight", "mike", "miller", "mine", "mistress", "money", "monica", "monkey", "monster", "morgan", "mother", "mountain", "movie", "muffin", "murphy", "music", "mustang", "naked", "nascar", "nathan", "naughty", "ncc1701", "newyork", "nicholas", "nicole", "ninja", "nipple", "nipples", "oliver", "orange", "ou812", "packers", "panther", "panties", "paris", "parker", "pass", "passw0rd", "password", "password1", "password12", "password123", "patrick", "paul", "peaches", "peanut", "penis", "pepper", "peter", "phantom", "phoenix", "photoshop", "player", "please", "pookie", "porn", "porno", "porsche", "power", "prince", "princess", "private", "purple", "pussies", "pussy", "qazwsx", "qwert", "qwerty", "qwertyui", "rabbit", "rachel", "racing", "raiders", "rainbow", "ranger", "rangers", "rebecca", "redskins", "redsox", "redwings", "richard", "robert", "rock", "rocket", "rosebud", "runner", "rush2112", "russia", "samantha", "sammy", "samson", "sandra", "saturn", "scooby", "scooter", "scorpio", "scorpion", "scott", "secret", "sexsex", "sexy", "shadow", "shannon", "shaved", "shit", "sierra", "silver", "skippy", "slayer", "slut", "smith", "smokey", "snoopy", "soccer", "sophie", "spanky", "sparky", "spider", "squirt", "srinivas", "star", "stars", "startrek", "starwars", "steelers", "steve", "steven", "sticky", "stupid", "success", "suckit", "summer", "sunshine", "super", "superman", "surfer", "swimming", "sydney", "taylor", "teens", "tennis", "teresa", "test", "tester", "testing", "theman", "thomas", "thunder", "thx1138", "tiffany", "tiger", "tigers", "tigger", "time", "tits", "tomcat", "topgun", "toyota", "travis", "trouble", "trustno1", "tucker", "turtle", "twitter", "united", "vagina", "victor", "victoria", "video", "viking", "viper", "voodoo", "voyager", "walter", "warrior", "welcome", "whatever", "white", "william", "willie", "wilson", "winner", "winston", "winter", "wizard", "wolf", "women", "xavier", "xxxx", "xxxxx", "xxxxxx", "xxxxxxxx", "yamaha", "yankee", "yankees", "yellow", "young", "zxcvbn", "zxcvbnm", "zzzzzz"];
268
+
269
+ return PasswordStrength;
270
+ })();