nobspw_rails7 0.6.5

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
+ 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