koodmeeter 0.0.2
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +112 -0
- data/Guardfile +6 -0
- data/LICENSE +674 -0
- data/README.md +41 -0
- data/Rakefile +7 -0
- data/data/blacklist.json +45 -0
- data/koodmeeter.gemspec +31 -0
- data/lib/koodmeeter.rb +4 -0
- data/lib/koodmeeter/axiom.rb +16 -0
- data/lib/koodmeeter/core.rb +65 -0
- data/lib/koodmeeter/version.rb +3 -0
- data/spec/lib/axiom_spec.rb +53 -0
- data/spec/lib/core_spec.rb +73 -0
- data/spec/spec_helper.rb +1 -0
- metadata +163 -0
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# koodmeeter [](https://travis-ci.org/ain/koodmeeter)
|
2
|
+
|
3
|
+
koodmeeter (codemeter) is a password strength score tool.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
``` ruby
|
8
|
+
# Returns number representing password strength score:
|
9
|
+
# 0 - lowest
|
10
|
+
# 5 - highest
|
11
|
+
Koodmeeter.check('mypassword')
|
12
|
+
```
|
13
|
+
|
14
|
+
Optionally, minimum chars option can be used, affecting score:
|
15
|
+
|
16
|
+
``` ruby
|
17
|
+
# Returns 0, since "mypassword" is less than 12 chars
|
18
|
+
Koodmeeter.check('mypassword', 12)
|
19
|
+
```
|
20
|
+
|
21
|
+
## Contributing
|
22
|
+
|
23
|
+
### Bug reports, suggestions
|
24
|
+
|
25
|
+
- File all your issues, feature requests [here](https://github.com/ain/koodmeeter/issues)
|
26
|
+
- If filing a bug report, follow the convention of [How to report a bug?](https://github.com/interactive-pioneers/conventions/blob/master/Bugtracking.md#how-to-report-a-bug)
|
27
|
+
- __If you're a developer, write a failing test instead of a bug report__ and send a Pull Request
|
28
|
+
|
29
|
+
### Code
|
30
|
+
|
31
|
+
1. Fork it ( https://github.com/[my-github-username]/koodmeeter/fork )
|
32
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
33
|
+
3. Develop your feature by concepts of [TDD](http://en.wikipedia.org/wiki/Test-driven_development). Run `guard` in parallel to automatically run your tests
|
34
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
35
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
36
|
+
5. Create a new Pull Request
|
37
|
+
|
38
|
+
|
39
|
+
## License
|
40
|
+
|
41
|
+
Copyright © 2015 Ain Tohvri. Licensed under [GPLv3](LICENSE).
|
data/Rakefile
ADDED
data/data/blacklist.json
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
{
|
2
|
+
"blacklist": [
|
3
|
+
"123456",
|
4
|
+
"12345",
|
5
|
+
"123456789",
|
6
|
+
"password",
|
7
|
+
"iloveyou",
|
8
|
+
"princess",
|
9
|
+
"rockyou",
|
10
|
+
"1234567",
|
11
|
+
"12345678",
|
12
|
+
"abc123",
|
13
|
+
"nicole",
|
14
|
+
"daniel",
|
15
|
+
"babygirl",
|
16
|
+
"monkey",
|
17
|
+
"jessica",
|
18
|
+
"lovely",
|
19
|
+
"michael",
|
20
|
+
"ashley",
|
21
|
+
"654321",
|
22
|
+
"qwerty",
|
23
|
+
"password1",
|
24
|
+
"welcome",
|
25
|
+
"welcome1",
|
26
|
+
"password2",
|
27
|
+
"password01",
|
28
|
+
"password3",
|
29
|
+
"p@ssw0rd",
|
30
|
+
"passw0rd",
|
31
|
+
"password4",
|
32
|
+
"password123",
|
33
|
+
"summer09",
|
34
|
+
"password6",
|
35
|
+
"password7",
|
36
|
+
"password9",
|
37
|
+
"password8",
|
38
|
+
"welcome2",
|
39
|
+
"welcome01",
|
40
|
+
"winter12",
|
41
|
+
"spring2012",
|
42
|
+
"summer12",
|
43
|
+
"summer2012"
|
44
|
+
]
|
45
|
+
}
|
data/koodmeeter.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "koodmeeter/version"
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "koodmeeter"
|
9
|
+
s.version = Koodmeeter::VERSION
|
10
|
+
s.authors = ["Ain Tohvri"]
|
11
|
+
s.email = ["ain@flashbit.net"]
|
12
|
+
s.summary = %q{koodmeeter (codemeter) is a password strength score tool.}
|
13
|
+
s.description = %q{koodmeeter is a port of koodmeeter.js password strength score tool.}
|
14
|
+
s.homepage = "https://github.com/ain/koodmeeter"
|
15
|
+
s.license = "GPL-3.0"
|
16
|
+
s.required_ruby_version = ">= 2.0.0"
|
17
|
+
|
18
|
+
s.files = `git ls-files -z`.split("\x0")
|
19
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
s.test_files = s.files.grep(%r{^spec/})
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_runtime_dependency "json", "~> 1.8"
|
24
|
+
|
25
|
+
s.add_development_dependency "rake", "~> 10.4"
|
26
|
+
s.add_development_dependency "rspec", "~> 3.2"
|
27
|
+
s.add_development_dependency "rspec-nc", "~> 0.2"
|
28
|
+
s.add_development_dependency "guard", "~> 2.12"
|
29
|
+
s.add_development_dependency "guard-rspec", "~> 4.5"
|
30
|
+
s.add_development_dependency "coveralls", "~> 0.8"
|
31
|
+
end
|
data/lib/koodmeeter.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Koodmeeter
|
2
|
+
class Axiom
|
3
|
+
def self.list
|
4
|
+
[
|
5
|
+
{ :regex => /[a-z]/, :score => 1 },
|
6
|
+
{ :regex => /[A-Z]/, :score => 5 },
|
7
|
+
{ :regex => /([a-z].*[A-Z])|([A-Z].*[a-z])/, :score => 2 },
|
8
|
+
{ :regex => /(.*[0-9].*[0-9].*[0-9])/, :score => 7 },
|
9
|
+
{ :regex => /.[!@#$%^&*?_~]/, :score => 5 },
|
10
|
+
{ :regex => /(.*[!@#$%^&*?_~].*[!@#$%^&*?_~])/, :score => 7 },
|
11
|
+
{ :regex => /([a-zA-Z0-9].*[!@#$%^&*?_~])|([!@#$%^&*?_~].*[a-zA-Z0-9])/, :score => 3 },
|
12
|
+
{ :regex => /(.)\1+$/, :score => 2 }
|
13
|
+
]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Koodmeeter
|
2
|
+
|
3
|
+
LEVELS = (0..5).to_a
|
4
|
+
DEFAULT_MIN_CHARS = 6
|
5
|
+
|
6
|
+
@@scores = [10, 15, 25, 45]
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def check(password, minimum_chars = DEFAULT_MIN_CHARS)
|
11
|
+
password = password.to_s
|
12
|
+
|
13
|
+
raise ArgumentError.new 'Password argument required!' if password.nil?
|
14
|
+
return 0 unless blacklist.index(password).nil?
|
15
|
+
|
16
|
+
length = password.length
|
17
|
+
diff = length - minimum_chars
|
18
|
+
scores_dupe = @@scores.dup
|
19
|
+
score = calculate_diff_increment(diff)
|
20
|
+
|
21
|
+
Axiom.list.each do |axiom|
|
22
|
+
if axiom[:regex].match(password)
|
23
|
+
score += axiom[:score]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
score += length
|
28
|
+
if score < 0 && score > -199
|
29
|
+
index = 0
|
30
|
+
else
|
31
|
+
scores_dupe.push(score).sort!
|
32
|
+
index = scores_dupe.index(score) + 1
|
33
|
+
end
|
34
|
+
|
35
|
+
return LEVELS[index].nil? ? LEVELS.last : LEVELS[index]
|
36
|
+
end
|
37
|
+
|
38
|
+
def blacklist
|
39
|
+
path = File.join root, 'data/blacklist.json'
|
40
|
+
file = File.read path
|
41
|
+
JSON.parse(file)['blacklist']
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def root
|
47
|
+
File.expand_path '../../..', __FILE__
|
48
|
+
end
|
49
|
+
|
50
|
+
def calculate_diff_increment(diff)
|
51
|
+
score = 0;
|
52
|
+
if diff < 0
|
53
|
+
score -= 100
|
54
|
+
elsif diff >= 5
|
55
|
+
score += 18
|
56
|
+
elsif diff >= 3
|
57
|
+
score += 12
|
58
|
+
elsif diff == 2
|
59
|
+
score += 6
|
60
|
+
end
|
61
|
+
return score
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Koodmeeter::Axiom do
|
4
|
+
|
5
|
+
describe '.list' do
|
6
|
+
context Koodmeeter::Axiom.list do
|
7
|
+
it { is_expected.to be_a Array }
|
8
|
+
end
|
9
|
+
|
10
|
+
context Koodmeeter::Axiom.list.length do
|
11
|
+
it { is_expected.to eql 8 }
|
12
|
+
end
|
13
|
+
|
14
|
+
context Koodmeeter::Axiom.list.first do
|
15
|
+
it { is_expected.to be_a Hash }
|
16
|
+
it { is_expected.to have_key :regex }
|
17
|
+
it { is_expected.to have_key :score }
|
18
|
+
end
|
19
|
+
|
20
|
+
context Koodmeeter::Axiom.list.first[:score] do
|
21
|
+
it { is_expected.to eql 1 }
|
22
|
+
end
|
23
|
+
|
24
|
+
context Koodmeeter::Axiom.list[1][:score] do
|
25
|
+
it { is_expected.to eql 5 }
|
26
|
+
end
|
27
|
+
|
28
|
+
context Koodmeeter::Axiom.list[2][:score] do
|
29
|
+
it { is_expected.to eql 2 }
|
30
|
+
end
|
31
|
+
|
32
|
+
context Koodmeeter::Axiom.list[3][:score] do
|
33
|
+
it { is_expected.to eql 7 }
|
34
|
+
end
|
35
|
+
|
36
|
+
context Koodmeeter::Axiom.list[4][:score] do
|
37
|
+
it { is_expected.to eql 5 }
|
38
|
+
end
|
39
|
+
|
40
|
+
context Koodmeeter::Axiom.list[5][:score] do
|
41
|
+
it { is_expected.to eql 7 }
|
42
|
+
end
|
43
|
+
|
44
|
+
context Koodmeeter::Axiom.list[6][:score] do
|
45
|
+
it { is_expected.to eql 3 }
|
46
|
+
end
|
47
|
+
|
48
|
+
context Koodmeeter::Axiom.list[7][:score] do
|
49
|
+
it { is_expected.to eql 2 }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Koodmeeter do
|
4
|
+
describe '.check' do
|
5
|
+
context 'without password' do
|
6
|
+
it { expect{ Koodmeeter.check }.to raise_error(ArgumentError) }
|
7
|
+
end
|
8
|
+
context 'with numeric password' do
|
9
|
+
it { expect{ Koodmeeter.check(21233) }.to_not raise_error }
|
10
|
+
end
|
11
|
+
context 'with blacklisted password' do
|
12
|
+
subject { Koodmeeter.check('123456') }
|
13
|
+
it { is_expected.to eql 0 }
|
14
|
+
|
15
|
+
subject { Koodmeeter.check('qwerty') }
|
16
|
+
it { is_expected.to eql 0 }
|
17
|
+
|
18
|
+
subject { Koodmeeter.check('lovely') }
|
19
|
+
it { is_expected.to eql 0 }
|
20
|
+
|
21
|
+
subject { Koodmeeter.check('password') }
|
22
|
+
it { is_expected.to eql 0 }
|
23
|
+
|
24
|
+
subject { Koodmeeter.check('welcome') }
|
25
|
+
it { is_expected.to eql 0 }
|
26
|
+
end
|
27
|
+
context 'with blacklisted password fed as number' do
|
28
|
+
subject { Koodmeeter.check(123456) }
|
29
|
+
it { is_expected.to eql 0 }
|
30
|
+
|
31
|
+
subject { Koodmeeter.check(12345) }
|
32
|
+
it { is_expected.to eql 0 }
|
33
|
+
end
|
34
|
+
context 'with 4 lowercase letters followed by a number' do
|
35
|
+
subject { Koodmeeter.check('asdf1') }
|
36
|
+
it { is_expected.to eql 0 }
|
37
|
+
end
|
38
|
+
context 'with 4 lowercase letters followed by 2 numbers' do
|
39
|
+
subject { Koodmeeter.check('asdf12') }
|
40
|
+
it { is_expected.to eql 1 }
|
41
|
+
end
|
42
|
+
context 'with 4 lowercase letters followed by 3 numbers' do
|
43
|
+
subject { Koodmeeter.check('asdf112') }
|
44
|
+
it { is_expected.to eql 2 }
|
45
|
+
end
|
46
|
+
context 'with 4 lowercase letters followed by 3 numbers and a dash' do
|
47
|
+
subject { Koodmeeter.check('asdf112-') }
|
48
|
+
it { is_expected.to eql 3 }
|
49
|
+
end
|
50
|
+
context 'with 4 lowercase letters followed by 3 numbers, a dash and a dollar' do
|
51
|
+
subject { Koodmeeter.check('asdf112-$') }
|
52
|
+
it { is_expected.to eql 4 }
|
53
|
+
end
|
54
|
+
context 'with 4 lowercase letters followed by 3 numbers, a dash, a dollar and 2 numbers' do
|
55
|
+
subject { Koodmeeter.check('asdf112-$55') }
|
56
|
+
it { is_expected.to eql 5 }
|
57
|
+
end
|
58
|
+
context 'with 8 minimum chars, 4 lowercase letters followed by 3 numbers, a dash, a dollar and 2 numbers' do
|
59
|
+
subject { Koodmeeter.check('asdf112-$55', 8) }
|
60
|
+
it { is_expected.to eql 4 }
|
61
|
+
end
|
62
|
+
context 'with 12 minimum chars, 4 lowercase letters followed by 3 numbers, a dash, a dollar and 2 numbers' do
|
63
|
+
subject { Koodmeeter.check('asdf112-$55', 12) }
|
64
|
+
it { is_expected.to eql 0 }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.blacklist' do
|
69
|
+
subject { Koodmeeter.blacklist }
|
70
|
+
it { is_expected.to be_a Array }
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'koodmeeter'
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: koodmeeter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ain Tohvri
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-nc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.8'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.8'
|
111
|
+
description: koodmeeter is a port of koodmeeter.js password strength score tool.
|
112
|
+
email:
|
113
|
+
- ain@flashbit.net
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- Gemfile.lock
|
123
|
+
- Guardfile
|
124
|
+
- LICENSE
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- data/blacklist.json
|
128
|
+
- koodmeeter.gemspec
|
129
|
+
- lib/koodmeeter.rb
|
130
|
+
- lib/koodmeeter/axiom.rb
|
131
|
+
- lib/koodmeeter/core.rb
|
132
|
+
- lib/koodmeeter/version.rb
|
133
|
+
- spec/lib/axiom_spec.rb
|
134
|
+
- spec/lib/core_spec.rb
|
135
|
+
- spec/spec_helper.rb
|
136
|
+
homepage: https://github.com/ain/koodmeeter
|
137
|
+
licenses:
|
138
|
+
- GPL-3.0
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 2.0.0
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.4.6
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: koodmeeter (codemeter) is a password strength score tool.
|
160
|
+
test_files:
|
161
|
+
- spec/lib/axiom_spec.rb
|
162
|
+
- spec/lib/core_spec.rb
|
163
|
+
- spec/spec_helper.rb
|