nobspw 0.1.0
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 +12 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/Guardfile +26 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/db/dictionary.txt +100000 -0
- data/lib/nobspw.rb +15 -0
- data/lib/nobspw/configuration.rb +21 -0
- data/lib/nobspw/password_checker.rb +114 -0
- data/lib/nobspw/version.rb +3 -0
- data/nobspw.gemspec +35 -0
- metadata +173 -0
data/lib/nobspw.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "nobspw/version"
|
2
|
+
|
3
|
+
module NOBSPW
|
4
|
+
autoload :PasswordChecker, 'nobspw/password_checker'
|
5
|
+
autoload :Configuration, 'nobspw/configuration'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.configure
|
12
|
+
self.configuration ||= Configuration.new
|
13
|
+
yield(configuration)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module NOBSPW
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :min_password_length
|
4
|
+
attr_accessor :max_password_length
|
5
|
+
attr_accessor :min_unique_characters
|
6
|
+
attr_accessor :dictionary_path
|
7
|
+
attr_accessor :grep_path
|
8
|
+
attr_accessor :domain_name
|
9
|
+
attr_accessor :blacklist
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@min_password_length = 10
|
13
|
+
@max_password_length = 256
|
14
|
+
@min_unique_characters = 5
|
15
|
+
@dictionary_path = File.join(File.dirname(__FILE__), "..", "db", "dictionary.txt")
|
16
|
+
@grep_path = `which grep`.strip
|
17
|
+
@domain_name = nil
|
18
|
+
@blacklist = nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module NOBSPW
|
2
|
+
class PasswordChecker
|
3
|
+
CHECKS = %i(name_included_in_password
|
4
|
+
email_included_in_password
|
5
|
+
domain_included_in_password
|
6
|
+
password_too_short
|
7
|
+
password_too_long
|
8
|
+
not_enough_unique_characters
|
9
|
+
password_blacklisted
|
10
|
+
password_too_common)
|
11
|
+
|
12
|
+
def initialize(name: nil, username: nil, email: nil, password:)
|
13
|
+
@name, @username, @email, @password = \
|
14
|
+
name.strip, username.strip, email.strip, password.strip
|
15
|
+
end
|
16
|
+
|
17
|
+
def strong?
|
18
|
+
check_password if @strong.nil?
|
19
|
+
@strong
|
20
|
+
end
|
21
|
+
|
22
|
+
def weak_password_reasons
|
23
|
+
check_password if @weak_password_reasons.nil?
|
24
|
+
@weak_password_reasons
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def check_password
|
30
|
+
@weak_password_reasons = []
|
31
|
+
|
32
|
+
CHECKS.each do |check|
|
33
|
+
@weak_password_reasons << check if send("#{check}?")
|
34
|
+
end
|
35
|
+
|
36
|
+
@strong = @weak_password_reasons.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
def name_included_in_password?
|
40
|
+
return nil unless @name
|
41
|
+
words = remove_word_separators(@name).split(' ')
|
42
|
+
words_included_in_password?(words)
|
43
|
+
end
|
44
|
+
|
45
|
+
def email_included_in_password?
|
46
|
+
return nil unless @email
|
47
|
+
words = remove_word_separators(email_without_extension(@email)).split(' ')
|
48
|
+
words_included_in_password?(words)
|
49
|
+
end
|
50
|
+
|
51
|
+
def domain_included_in_password?
|
52
|
+
domain = NOBSPW.configuration.domain_name
|
53
|
+
return nil unless domain
|
54
|
+
|
55
|
+
words_included_in_password?(domain) ||
|
56
|
+
remove_word_separators(words_included_in_password?(domain)).gsub(' ', '')
|
57
|
+
end
|
58
|
+
|
59
|
+
def password_blacklisted?
|
60
|
+
return nil unless NOBSPW.configuration.blacklist
|
61
|
+
NOBSPW.configuration.blacklist.include?(@password)
|
62
|
+
end
|
63
|
+
|
64
|
+
def password_too_short?
|
65
|
+
@password.length < NOBSPW.configuration.min_password_length
|
66
|
+
end
|
67
|
+
|
68
|
+
def password_too_long?
|
69
|
+
@password.length > NOBSPW.configuration.max_password_length
|
70
|
+
end
|
71
|
+
|
72
|
+
def not_enough_unique_characters?
|
73
|
+
unique = @password.split(//).uniq.size
|
74
|
+
minimum = NOBSPW.configuration.min_unique_characters
|
75
|
+
!(unique >= minimum)
|
76
|
+
end
|
77
|
+
|
78
|
+
def words_included_in_password?(words)
|
79
|
+
downcased_pw = @password.downcase
|
80
|
+
words.each do |word|
|
81
|
+
return true if word.length > 2 && downcased_pw.index(word.downcase)
|
82
|
+
end; false
|
83
|
+
end
|
84
|
+
|
85
|
+
def password_too_common?
|
86
|
+
`#{grep_command(NOBSPW.configuration.dictionary_path)}`
|
87
|
+
|
88
|
+
case $?.exitstatus
|
89
|
+
when 0
|
90
|
+
true
|
91
|
+
when 1
|
92
|
+
false
|
93
|
+
when 127
|
94
|
+
raise StandardError.new("Grep not found at: #{NOBSPW.configuration.grep_path}")
|
95
|
+
else
|
96
|
+
false
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def grep_command(path)
|
101
|
+
"#{NOBSPW.configuration.grep_path} '^#{@password}$' #{path}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def email_without_extension(email)
|
105
|
+
name, domain, whatev = email.split("@", 3)
|
106
|
+
"#{name}@#{domain}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def remove_word_separators(str)
|
110
|
+
str.gsub(/-|_|\.|\'|\"|\@/, ' ')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
data/nobspw.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nobspw/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "nobspw"
|
8
|
+
spec.version = NOBSPW::VERSION
|
9
|
+
spec.authors = ["Carl Mercier"]
|
10
|
+
spec.email = ["foss@carlmercier.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{No Bullshit Password strength checker}
|
13
|
+
spec.description = %q{No Bullshit Password strength checker. Inspired by "Password Rules are Bullshit" by Jeff Atwood. https://blog.codinghorror.com/password-rules-are-bullshit/}
|
14
|
+
spec.homepage = "https://github.com/cmer/nobspw"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "simplecov", "~> 0.13"
|
28
|
+
spec.add_development_dependency "guard", "~> 2.14"
|
29
|
+
spec.add_development_dependency "guard-rspec", "~> 4.7.3"
|
30
|
+
|
31
|
+
if RUBY_PLATFORM =~ /darwin/
|
32
|
+
spec.add_development_dependency 'ruby_gntp', "~> 0.3.4"
|
33
|
+
spec.add_development_dependency 'terminal-notifier-guard', '~> 1.6.1'
|
34
|
+
end
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nobspw
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carl Mercier
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
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.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
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.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.13'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.13'
|
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.14'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.14'
|
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.7.3
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 4.7.3
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ruby_gntp
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.3.4
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.3.4
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: terminal-notifier-guard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.6.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.6.1
|
125
|
+
description: No Bullshit Password strength checker. Inspired by "Password Rules are
|
126
|
+
Bullshit" by Jeff Atwood. https://blog.codinghorror.com/password-rules-are-bullshit/
|
127
|
+
email:
|
128
|
+
- foss@carlmercier.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
|
+
- Gemfile
|
137
|
+
- Guardfile
|
138
|
+
- LICENSE.txt
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- bin/console
|
142
|
+
- bin/setup
|
143
|
+
- lib/db/dictionary.txt
|
144
|
+
- lib/nobspw.rb
|
145
|
+
- lib/nobspw/configuration.rb
|
146
|
+
- lib/nobspw/password_checker.rb
|
147
|
+
- lib/nobspw/version.rb
|
148
|
+
- nobspw.gemspec
|
149
|
+
homepage: https://github.com/cmer/nobspw
|
150
|
+
licenses:
|
151
|
+
- MIT
|
152
|
+
metadata: {}
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubyforge_project:
|
169
|
+
rubygems_version: 2.5.2
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: No Bullshit Password strength checker
|
173
|
+
test_files: []
|