nobspw_rails7 0.6.5

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2ca5d47ab1262a8a04bece3bbcac0936b803458df38c09b94461f163815b206f
4
+ data.tar.gz: e33e55cdd6068f454c2ad46a1e8864809399f780f594726bb3623ed13314a5cb
5
+ SHA512:
6
+ metadata.gz: 924d72215ed541b7f74f5fb7675d893df4dfa30b0e45b3e13b4d63e55f5b778987441f9b8f1d30d2797fe487889d5f11a4b64ed1cd6b754923fe8a51104c14fd
7
+ data.tar.gz: 8e6878728ca1b2592db6b5dd4e8d9d6299c0073c040dc7912e7f41bcbc861832a5e93e28a8f5a450c36ab8d09b2eb8b7181022230b1134a3565a070e013405f8
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /coverage/
11
+ /spec/examples.txt
12
+ *.gem
13
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.0
5
+ - 2.6.2
6
+ - 2.7.1
7
+ before_install: gem install bundler
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nobspw_rails7.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,26 @@
1
+ guard :rspec, cmd: "bundle exec rspec" do
2
+ require "guard/rspec/dsl"
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # Feel free to open issues for suggestions and improvements
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
17
+
18
+ if `uname` =~ /Darwin/
19
+ if !!system("lsof -i:23053", out: '/dev/null')
20
+ puts "Growl notifications enabled"
21
+ notification :gntp, app_name: "", activate: 'com.googlecode.iTerm2'
22
+ else
23
+ puts "Native macOS notifications enabled"
24
+ notification :terminal_notifier, app_name: "", activate: 'com.googlecode.iTerm2' if `uname` =~ /Darwin/
25
+ end
26
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Carl Mercier
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # NOBSPW_RAILS7 - No Bullshit Password strength checker
2
+
3
+ [![Build Status](https://travis-ci.org/cmer/nobspw_rails7.svg?branch=master)](https://travis-ci.org/cmer/nobspw_rails7)
4
+
5
+ NOBSPW_RAILS7 is simple, no non-sense password strength checker written in Ruby. It does NOT validate against [bullshit password rules](https://twitter.com/codinghorror/status/631238409269309440?ref_src=twsrc%5Etfw) such as:
6
+
7
+ - must contain uppercase _(bullshit!)_
8
+ - must contain lowercase _(bullshit!)_
9
+ - must contain a number _(bullshit!)_
10
+ - must contain a special character _(bullshit!)_
11
+
12
+ Instead, it validates your user's password against a few important criteria. This ensures strong passwords without the hassle generally associated with complex (and useless) password rules.
13
+
14
+ The criteria currently are:
15
+
16
+ - enforce minimum (and maximum) length. 10 characters is the recommended minimum and is the default value
17
+ - reject common passwords from a dictionary of the 100,000 most common passwords (or your own dictionary)
18
+ - requires basic entropy (not too many of the same character)
19
+ - reject special case passwords such as the user's name, email, domain of the site/app
20
+
21
+ This software was inspired by [Password Rules are Bullshit](https://blog.codinghorror.com/password-rules-are-bullshit/) by Jeff Atwood.
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ ```ruby
28
+ gem 'nobspw_rails7'
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install nobspw_rails7
38
+
39
+ ## Usage
40
+
41
+ ### Vanilla Ruby
42
+
43
+ ```ruby
44
+ pwc = NOBSPW_RAILS7::PasswordChecker.new password: 'mystrongpassword',
45
+ name: 'John Smith', # optional but recommended
46
+ username: 'bigjohn43', # optional but recommended
47
+ email: 'john@example.org' # optional but recommended
48
+ pwc.strong?
49
+ pwc.weak?
50
+ pwd.weak_password_reasons # returns an array of Symbols with reasons why password is weak
51
+ pwd.reasons # short alias of weak_password_reasons
52
+ ```
53
+
54
+ Optionally, you can configure some options:
55
+
56
+ ```ruby
57
+ NOBSPW_RAILS7.configure do |config|
58
+ config.min_password_length = 10
59
+ config.max_password_length = 256
60
+ config.min_unique_characters = 5
61
+ config.dictionary_path = 'path/to/dictionary.txt'
62
+ config.grep_path = '/usr/bin/grep'
63
+ config.use_ruby_grep = false # Defaults to false; slower when true. Uses Ruby's internal Grep method instead of shelling out.
64
+ config.domain_name = 'mywebsitedomain.com' # it is recommended you configure this
65
+ config.blacklist = ['this_password_is_not_allowed', /password/]
66
+ end
67
+ ```
68
+
69
+ ### Ruby on Rails
70
+
71
+ I included `PasswordValidator` for Rails. Validating passwords in your model couldn't be easier:
72
+
73
+ ```ruby
74
+ validates :password, presence: true, password: true, if: -> { new_record? || changes[:password] || changes[:password_digest] }
75
+ ```
76
+
77
+ PasswordValidator will try to guess the correct field name for each `PasswordChecker` argument as follow:
78
+
79
+ - `username`: `username` `user_name` `user` `screenname` `screen_name`
80
+ - `name`: `name` `full_name` `first_name+last_name`
81
+ - `email`: `email` `email_address`
82
+
83
+ If you have field names different than above, you can tell `PasswordValidator` which fields to use for specific attributes:
84
+
85
+ ```ruby
86
+ validates :password, password: { :name => :customer_name,
87
+ :email => :electronic_address },
88
+ if: -> { new_record? || changes[:password] || changes[:password_digest] }
89
+ ```
90
+
91
+ ## Validations
92
+
93
+ NOBSPW_RAILS7 currently validates for the following, in this order:
94
+
95
+ ```ruby
96
+ password_empty?
97
+ name_included_in_password?
98
+ email_included_in_password?
99
+ domain_included_in_password?
100
+ password_too_short?
101
+ password_too_long?
102
+ not_enough_unique_characters?
103
+ password_not_allowed?
104
+ password_too_common?
105
+ ```
106
+ If any of these tests fail, they'll be returned by `#reasons`, or with Rails, they'll be added to `errors[:password]`.
107
+
108
+
109
+ ## Custom Validations
110
+
111
+ It is possible and easy to add your own validations, or remove default ones.
112
+
113
+ ### Adding a custom validation
114
+
115
+ ```ruby
116
+ module NOBSPW_RAILS7::ValidationMethods
117
+ def contains_letter_a?
118
+ # This is obviously a silly validation. Don't do this!
119
+ # If method returns true, it means that it FAILED validation.
120
+ # For example, it does contain the letter a and it's not considered acceptable.
121
+ !!@password.downcase.index('a')
122
+ end
123
+ end
124
+
125
+ NOBSPW_RAILS7.configuration.validation_methods << :contains_letter_a?
126
+
127
+ # if using the Rails validator, you also need to define the error message:
128
+ ActiveModel::Validations::PasswordValidator.error_messages[:contains_letter_a] = \
129
+ 'contains an unacceptable character'
130
+
131
+ ```
132
+
133
+ ### Removing a built-in validation
134
+
135
+ ```ruby
136
+ NOBSPW_RAILS7.configuration.validation_methods.delete(:domain_included_in_password?)
137
+ ```
138
+
139
+ ### Localization
140
+
141
+ You can localize all error messages, including custom ones, using I18n.
142
+
143
+ See `PasswordValidator#get_message` and `PasswordValidator#DEFAULT_ERROR_MESSAGES` for implementation details.
144
+
145
+
146
+
147
+ ## License
148
+
149
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
150
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "nobspw_rails7"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,84 @@
1
+ class ActiveModel::Validations::PasswordValidator < ActiveModel::EachValidator
2
+ DEFAULT_ERROR_MESSAGES = {
3
+ name_included_in_password: 'is too similar to your name',
4
+ username_included_in_password: 'is too similar to your username',
5
+ email_included_in_password: 'is too similar to your email',
6
+ domain_included_in_password: 'is too similar to this domain name',
7
+ password_too_short: 'is too short',
8
+ password_too_long: 'is too long',
9
+ not_enough_unique_characters: 'does not have enough unique characters',
10
+ password_not_allowed: 'is not allowed',
11
+ password_too_common: 'is too common',
12
+ fallback: 'is not valid'
13
+ }
14
+
15
+ def validate_each(record, attribute, value)
16
+ pc = NOBSPW_RAILS7::PasswordChecker.new password: record.send(attribute),
17
+ email: email_value(record),
18
+ name: name_value(record),
19
+ username: username_value(record)
20
+
21
+ pc.weak_password_reasons.each do |reason|
22
+ record.errors.add(attribute, get_message(reason))
23
+ end
24
+ pc.strong?
25
+ end
26
+
27
+ def error_messages
28
+ @error_messages ||= DEFAULT_ERROR_MESSAGES
29
+ end
30
+
31
+ def error_messages=(em)
32
+ @error_messages = em
33
+ end
34
+
35
+ private
36
+
37
+ def email_value(record)
38
+ if options.keys.include?(:email)
39
+ return nil if options[:email].nil?
40
+ return record.send(options[:email])
41
+ end
42
+
43
+ %i(email email_address).each do |f|
44
+ return record.send(f) if record.respond_to?(f)
45
+ end
46
+
47
+ nil
48
+ end
49
+
50
+ def username_value(record)
51
+ if options.keys.include?(:username)
52
+ return nil if options[:username].nil?
53
+ return record.send(options[:username])
54
+ end
55
+
56
+ %i(username user_name user screenname screen_name).each do |f|
57
+ return record.send(f) if record.respond_to?(f)
58
+ end
59
+
60
+ nil
61
+ end
62
+
63
+ def name_value(record)
64
+ if options.keys.include?(:name)
65
+ return nil if options[:name].nil?
66
+ return record.send(options[:name])
67
+ end
68
+
69
+ %i(name full_name).each do |f|
70
+ return record.send(f) if record.respond_to?(f)
71
+ end
72
+
73
+ if record.respond_to?(:first_name) && record.respond_to?(:last_name)
74
+ return "#{record.send(:first_name)} #{record.send(:last_name)}"
75
+ end
76
+
77
+ nil
78
+ end
79
+
80
+ def get_message(reason)
81
+ I18n.t "password_validator.#{reason}", default: error_messages[reason] ||
82
+ error_messages[:fallback]
83
+ end
84
+ end