passwd 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -17
  3. data/.travis.yml +3 -11
  4. data/Gemfile +3 -1
  5. data/LICENSE +21 -0
  6. data/README.md +39 -53
  7. data/Rakefile +6 -6
  8. data/bin/console +7 -0
  9. data/bin/setup +8 -0
  10. data/lib/generators/passwd/install/USAGE +5 -0
  11. data/lib/generators/passwd/install/install_generator.rb +10 -0
  12. data/lib/generators/passwd/install/templates/passwd.rb +27 -0
  13. data/lib/passwd.rb +33 -15
  14. data/lib/passwd/config.rb +29 -0
  15. data/lib/passwd/errors.rb +2 -7
  16. data/lib/passwd/rails/action_controller_ext.rb +77 -0
  17. data/lib/passwd/rails/active_record_ext.rb +37 -0
  18. data/lib/passwd/railtie.rb +5 -6
  19. data/lib/passwd/version.rb +2 -2
  20. data/passwd.gemspec +13 -14
  21. metadata +22 -156
  22. data/.coveralls.yml +0 -1
  23. data/CHANGELOG.md +0 -35
  24. data/LICENSE.txt +0 -23
  25. data/example/.gitignore +0 -16
  26. data/example/Gemfile +0 -25
  27. data/example/README.rdoc +0 -28
  28. data/example/Rakefile +0 -6
  29. data/example/app/assets/images/.keep +0 -0
  30. data/example/app/assets/javascripts/application.js +0 -16
  31. data/example/app/assets/stylesheets/application.css +0 -16
  32. data/example/app/controllers/application_controller.rb +0 -10
  33. data/example/app/controllers/concerns/.keep +0 -0
  34. data/example/app/controllers/profiles_controller.rb +0 -28
  35. data/example/app/controllers/root_controller.rb +0 -5
  36. data/example/app/controllers/sessions_controller.rb +0 -29
  37. data/example/app/helpers/application_helper.rb +0 -2
  38. data/example/app/mailers/.keep +0 -0
  39. data/example/app/models/.keep +0 -0
  40. data/example/app/models/concerns/.keep +0 -0
  41. data/example/app/models/user.rb +0 -4
  42. data/example/app/views/layouts/application.html.erb +0 -15
  43. data/example/app/views/profiles/edit.html.erb +0 -14
  44. data/example/app/views/profiles/show.html.erb +0 -12
  45. data/example/app/views/root/index.html.erb +0 -5
  46. data/example/app/views/sessions/new.html.erb +0 -6
  47. data/example/bin/bundle +0 -3
  48. data/example/bin/rails +0 -4
  49. data/example/bin/rake +0 -4
  50. data/example/config.ru +0 -4
  51. data/example/config/application.rb +0 -40
  52. data/example/config/boot.rb +0 -4
  53. data/example/config/database.yml +0 -26
  54. data/example/config/environment.rb +0 -5
  55. data/example/config/environments/development.rb +0 -37
  56. data/example/config/environments/production.rb +0 -78
  57. data/example/config/environments/test.rb +0 -39
  58. data/example/config/initializers/assets.rb +0 -8
  59. data/example/config/initializers/backtrace_silencers.rb +0 -7
  60. data/example/config/initializers/cookies_serializer.rb +0 -3
  61. data/example/config/initializers/filter_parameter_logging.rb +0 -4
  62. data/example/config/initializers/inflections.rb +0 -16
  63. data/example/config/initializers/mime_types.rb +0 -4
  64. data/example/config/initializers/passwd.rb +0 -41
  65. data/example/config/initializers/session_store.rb +0 -3
  66. data/example/config/initializers/wrap_parameters.rb +0 -14
  67. data/example/config/locales/en.yml +0 -23
  68. data/example/config/routes.rb +0 -16
  69. data/example/config/secrets.yml +0 -22
  70. data/example/db/migrate/20141122165914_create_users.rb +0 -13
  71. data/example/db/schema.rb +0 -25
  72. data/example/db/seeds.rb +0 -7
  73. data/example/lib/assets/.keep +0 -0
  74. data/example/lib/tasks/.keep +0 -0
  75. data/example/lib/tasks/user.rake +0 -12
  76. data/example/log/.keep +0 -0
  77. data/example/public/404.html +0 -67
  78. data/example/public/422.html +0 -67
  79. data/example/public/500.html +0 -66
  80. data/example/public/favicon.ico +0 -0
  81. data/example/public/robots.txt +0 -5
  82. data/example/vendor/assets/javascripts/.keep +0 -0
  83. data/example/vendor/assets/stylesheets/.keep +0 -0
  84. data/lib/generators/passwd/config_generator.rb +0 -13
  85. data/lib/generators/passwd/templates/passwd_config.rb +0 -41
  86. data/lib/passwd/action_controller_ext.rb +0 -48
  87. data/lib/passwd/active_record_ext.rb +0 -65
  88. data/lib/passwd/base.rb +0 -31
  89. data/lib/passwd/configuration.rb +0 -82
  90. data/lib/passwd/password.rb +0 -89
  91. data/lib/passwd/policy.rb +0 -28
  92. data/lib/passwd/salt.rb +0 -50
  93. data/spec/passwd/.keep +0 -0
  94. data/spec/passwd/active_record_ext_spec.rb +0 -80
  95. data/spec/passwd/base_spec.rb +0 -60
  96. data/spec/passwd/configuration_spec.rb +0 -50
  97. data/spec/passwd/password_spec.rb +0 -156
  98. data/spec/spec_helper.rb +0 -34
  99. data/spec/support/data_util.rb +0 -11
  100. data/spec/support/paths.rb +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 15f7af650246f9de96bc2aa84b2a6be0f7057b43
4
- data.tar.gz: 9d30c7e3e157b1bd21942502ec7664d0733650b9
3
+ metadata.gz: 4315761117ee941709bb71c7eb31757f2a5b7ec2
4
+ data.tar.gz: ad9db1a83f918d12d53a6ac15f4d3cb39e8f3c9b
5
5
  SHA512:
6
- metadata.gz: 2fec9addec10e3bec27923d51a94ceea7a5d6c82c12085fd8639990dd23ac6c922899b2ca01e1959aad83438a99a48dbc695df2e06c006c70d5733ae9dc92291
7
- data.tar.gz: c1da0f7170c0ee57591d584cbc7bb72f3f37461dd52d6bc95877ce305785527f0f3e1a9a8f3d1f36aaca620316ff59d585331d16677aa01e030cd9ebd89c1246
6
+ metadata.gz: d8025a6e85f67eacdf856281b17ceef650fb354e48fbafe1a4c06c979a7d2e1bf98ed1e4d812d3429b141945f1f7cbb0bcd7652b1ca65a288ba0583ba7ad971c
7
+ data.tar.gz: 780295751daffe7ebda019356f62aac1f56fe5a388b09281d8a8889654feb5d97d2f527c0de3c85f8344e1e41351887068202493d1cb5994022bfda4ebe83a71
data/.gitignore CHANGED
@@ -1,17 +1,10 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ /Gemfile.lock
@@ -1,13 +1,5 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.0
5
- branches:
6
- only:
7
- - master
8
- gemfile:
9
- - Gemfile
10
- script: bundle exec rake spec
11
- notifications:
12
- mails:
13
- - i2bskn@gmail.com
4
+ - 2.5.1
5
+ before_install: gem install bundler -v 1.16.2
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
2
4
 
3
5
  # Specify your gem's dependencies in passwd.gemspec
4
6
  gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2013-2018 Ken Iiboshi
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,11 +1,8 @@
1
1
  # Passwd
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/passwd.svg)](http://badge.fury.io/rb/passwd)
4
- [![Build Status](https://travis-ci.org/i2bskn/passwd.svg?branch=master)](https://travis-ci.org/i2bskn/passwd)
5
- [![Coverage Status](https://img.shields.io/coveralls/i2bskn/passwd.svg)](https://coveralls.io/r/i2bskn/passwd?branch=master)
6
- [![Code Climate](https://codeclimate.com/github/i2bskn/passwd/badges/gpa.svg)](https://codeclimate.com/github/i2bskn/passwd)
7
4
 
8
- Password utilities and integration to Rails.
5
+ Passwd is provide hashed password creation and authentication.
9
6
 
10
7
  ## Installation
11
8
 
@@ -17,10 +14,31 @@ gem "passwd"
17
14
 
18
15
  And then execute:
19
16
 
20
- $ bundle
17
+ ```
18
+ $ bundle install
19
+ ```
20
+
21
+ Create config file(Only Rails) with:
22
+
23
+ ```
24
+ $ bundle exec rails generate passwd:install
25
+ ```
26
+
27
+ The following file will be created.
28
+ See [config](https://github.com/i2bskn/passwd/blob/master/lib/generators/passwd/install/templates/passwd.rb) if not Rails.
29
+
30
+ - `config/initializers/passwd.rb`
21
31
 
22
32
  ## Usage
23
33
 
34
+ ### Ruby
35
+
36
+ ```ruby
37
+ passwd = Passwd.current
38
+ passwd.random(10) # Create random password of 10 characters.
39
+ passwd.hashed_password("secret", "salt") # Create hashed password with stretching.
40
+ ```
41
+
24
42
  ### ActiveRecord with Rails
25
43
 
26
44
  Add authentication to your `User` model.
@@ -57,39 +75,20 @@ Returns nil if authentication fails or doesn't exists user.
57
75
  Instance method is not required `id`.
58
76
 
59
77
  ```ruby
60
- user = User.authenticate(params[:email], params[:password]) # => return user object or nil.
61
- user.authenticate(params[:password])
78
+ user = User.authenticate(params[:email], params[:password]) # Returns user object or nil.
79
+ user.authenticate(params[:password]) # Returns true if authentication succeeded.
62
80
  ```
63
81
 
64
82
  `set_password` method will be set random password.
65
83
  To specify password as an argument if you want to specify a password.
66
84
 
67
85
  ```ruby
68
- current_user.set_password("secret") # => random password if not specified a argument.
69
- current_user.passwd.plain # => new password
86
+ current_user.set_password("secret") # Set random password if not specified a argument.
70
87
  current_user.save
71
88
 
72
89
  new_user = User.new
73
- password = new_user.passwd.plain
74
- UserMailer.register(new_user, password).deliver!
75
- ```
76
-
77
- `update_password` method will be set new password if the authentication successful.
78
- But `update_password` method doesn't call `save` method.
79
-
80
- ```ruby
81
- # update_password(OLD_PASSWORD, NEW_PASSWORD[, POLICY_CHECK=false])
82
- current_user.update_password(old_pass, new_pass, true)
83
- current_user.save
84
- ```
85
-
86
- #### Policy check
87
-
88
- Default policy is 8 more characters and require lower case and require number.
89
- Can be changed in configuration file.
90
-
91
- ```ruby
92
- Passwd.policy_check("secret") # => true or false
90
+ random_plain_password = new_user.set_password
91
+ UserMailer.register(new_user, random_plain_password).deliver!
93
92
  ```
94
93
 
95
94
  ### ActionController
@@ -123,8 +122,8 @@ class SessionsController < ApplicationController
123
122
 
124
123
  if @user
125
124
  # Save user_id to session
126
- signin!(@user)
127
- redirect_to some_url, notice: "Signin was successful. Hello #{current_user.name}"
125
+ signin(@user)
126
+ redirect_to_referer_or some_path, notice: "Signin was successful. Hello #{current_user.name}"
128
127
  else # Authentication fails
129
128
  render action: :new
130
129
  end
@@ -133,38 +132,25 @@ class SessionsController < ApplicationController
133
132
  # DELETE /signout
134
133
  def destroy
135
134
  # Clear session (Only user_id)
136
- signout!
137
- redirect_to some_url
135
+ signout
136
+ redirect_to some_path
138
137
  end
139
138
  end
140
139
  ```
141
140
 
142
- `current_user` method available if already signin.
141
+ `current_user` and `signin?` method available in controllers and views.
143
142
 
144
143
  ```ruby
145
- # app/controllers/greet_controller.rb
146
144
  def greet
147
- render text: "Hello #{current_user.name}!!"
145
+ name = signin? ? current_user.name : "Guest"
146
+ render text: "Hello #{name}!!"
148
147
  end
149
-
150
- # app/views/greet/greet.html.erb
151
- <p>Hello <%= current_user.name %>!!<p>
152
- ```
153
-
154
- ### Generate configuration file
155
-
156
- Run generator of Rails.
157
- Configuration file created to `config/initializers/passwd.rb`.
158
-
159
- ```
160
- $ bundle exec rails generate passwd:config
161
148
  ```
162
149
 
163
150
  ## Contributing
164
151
 
165
- 1. Fork it ( https://github.com/i2bskn/passwd/fork )
166
- 2. Create your feature branch (`git checkout -b my-new-feature`)
167
- 3. Commit your changes (`git commit -am 'Add some feature'`)
168
- 4. Push to the branch (`git push origin my-new-feature`)
169
- 5. Create a new Pull Request
152
+ Bug reports and pull requests are welcome on GitHub at https://github.com/i2bskn/passwd.
153
+
154
+ ## License
170
155
 
156
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,10 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
2
+ require "rake/testtask"
3
3
 
4
- desc "Run all specs"
5
- RSpec::Core::RakeTask.new(:spec) do |t|
6
- t.rspec_opts = %w(--color --format documentation)
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
7
8
  end
8
9
 
9
- task :default => :spec
10
-
10
+ task :default => :test
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "passwd"
5
+
6
+ require "pry"
7
+ Pry.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install --path .bundle
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Create Passwd config file.
3
+
4
+ Example:
5
+ rails generate passwd:install
@@ -0,0 +1,10 @@
1
+ module Passwd::Generators
2
+ class InstallGenerator < Rails::Generators::Base
3
+ source_root File.expand_path("templates", __dir__)
4
+
5
+ desc "Create Passwd config file"
6
+ def create_config_file
7
+ copy_file "passwd.rb", "config/initializers/passwd.rb"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ Passwd.current.config.tap do |config|
2
+ # Hashing algorithm
3
+ # Supported algorithm is :md5, :rmd160, :sha1, :sha256, :sha384 and :sha512
4
+ # config.algorithm = :sha512
5
+
6
+ # Number of hashed by stretching
7
+ # Not stretching if specified nil or 0.
8
+ # config.stretching = 100
9
+
10
+ # Random generate password length
11
+ # config.length = 10
12
+
13
+ # Array of characters used for random password generation
14
+ # config.characters = [("a".."z"), ("A".."Z"), ("0".."9")].map(&:to_a).flatten
15
+ end
16
+
17
+ # Session key for authentication
18
+ # Rails.application.config.passwd.session_key = :user_id
19
+
20
+ # Authentication Model Class
21
+ # Rails.application.config.passwd.auth_class = :User
22
+
23
+ # Redirect path when not signin
24
+ # Rails.application.config.passwd.signin_path = :signin_path
25
+
26
+ # Salt generation logic
27
+ # Rails.application.config.passwd.random_salt = proc { SecureRandom.uuid }
@@ -1,25 +1,43 @@
1
- require "digest/sha1"
2
- require "digest/sha2"
1
+ require "digest"
2
+ require "securerandom"
3
3
 
4
4
  require "passwd/version"
5
5
  require "passwd/errors"
6
- require "passwd/policy"
7
- require "passwd/configuration"
8
- require "passwd/base"
9
- require "passwd/salt"
10
- require "passwd/password"
6
+ require "passwd/config"
11
7
  require "passwd/railtie" if defined?(Rails)
12
8
 
13
- module Passwd
14
- extend Base
15
- extend Configuration::Writable
9
+ class Passwd
10
+ class << self
11
+ def current
12
+ @current ||= new
13
+ end
16
14
 
17
- def self.policy_check(plain)
18
- Password.from_plain(plain).valid?
15
+ def current=(passwd)
16
+ @current = passwd
17
+ end
19
18
  end
20
19
 
21
- def self.match?(plain, salt_hash, hash)
22
- Password.from_hash(hash, salt_hash).match?(plain)
20
+ def initialize(conf = nil)
21
+ @config = conf
22
+ end
23
+
24
+ def hashed_password(plain, salt)
25
+ config.stretching.to_i.times.with_object([digest_class.hexdigest([plain, salt].join)]) { |_, pass|
26
+ pass[0] = digest_class.hexdigest(pass[0])
27
+ }.first
28
+ end
29
+
30
+ def random(n = nil)
31
+ Array.new(n || config.length) { config.characters[rand(config.characters.size)] }.join
23
32
  end
24
- end
25
33
 
34
+ def config
35
+ @config ||= Config.new
36
+ end
37
+
38
+ private
39
+
40
+ def digest_class
41
+ Digest.const_get(config.algorithm.upcase)
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ class Passwd
2
+ class Config
3
+ VALID_OPTIONS = [
4
+ :algorithm,
5
+ :stretching,
6
+ :length,
7
+ :characters,
8
+ ].freeze
9
+
10
+ attr_accessor *VALID_OPTIONS
11
+
12
+ def initialize(options = {})
13
+ reset
14
+ merge(options)
15
+ end
16
+
17
+ def merge(options)
18
+ options.keys.each { |key| send("#{key}=", options[key]) }
19
+ self
20
+ end
21
+
22
+ def reset
23
+ @algorithm = :sha512
24
+ @stretching = 100
25
+ @length = 10
26
+ @characters = [("a".."z"), ("A".."Z"), ("0".."9")].map(&:to_a).flatten
27
+ end
28
+ end
29
+ end
@@ -1,8 +1,3 @@
1
- module Passwd
2
- class PasswdError < StandardError; end
3
- class UnauthorizedAccess < PasswdError; end
4
- class PolicyNotMatch < PasswdError; end
5
- class AuthenticationFails < PasswdError; end
6
- class ConfigError < PasswdError; end
1
+ class Passwd
2
+ class UnauthorizedAccess < StandardError; end
7
3
  end
8
-
@@ -0,0 +1,77 @@
1
+ module Passwd::Rails
2
+ module ActionControllerExt
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ helper_method :current_user, :signin?
7
+ end
8
+
9
+ private
10
+
11
+ def current_user
12
+ return @current_user if instance_variable_defined?(:@current_user)
13
+
14
+ @current_user = _auth_class.find_by(id: session[_auth_key])
15
+ end
16
+
17
+ def signin?
18
+ current_user.present?
19
+ end
20
+
21
+ def signin(user)
22
+ if user.present?
23
+ @current_user = user
24
+ session[_auth_key] = user&.id
25
+ end
26
+
27
+ user.present?
28
+ end
29
+
30
+ def signout
31
+ session[_auth_key] = nil
32
+ @current_user = nil
33
+ end
34
+
35
+ def redirect_to_referer_or(path, options = {})
36
+ redirect_to session[:referer].presence || path, **options
37
+ end
38
+
39
+ def require_signin
40
+ unless signin?
41
+ path = _signin_path
42
+ raise UnauthorizedAccess unless path
43
+ session[:referer] = request.fullpath
44
+ redirect_to path
45
+ end
46
+ end
47
+
48
+ def passwd_auth_class
49
+ nil
50
+ end
51
+
52
+ def passwd_auth_key
53
+ nil
54
+ end
55
+
56
+ def passwd_signin_path
57
+ nil
58
+ end
59
+
60
+ def _auth_class
61
+ (Rails.application.config.passwd.auth_class || passwd_auth_class || :User).to_s.constantize
62
+ end
63
+
64
+ def _auth_key
65
+ Rails.application.config.passwd.session_key || passwd_auth_key || :user_id
66
+ end
67
+
68
+ def _signin_path
69
+ name = Rails.application.config.passwd.signin_path || passwd_signin_path || :signin_path
70
+ _url_helpers.respond_to?(name) ? _url_helpers.public_send(name) : nil
71
+ end
72
+
73
+ def _url_helpers
74
+ Rails.application.routes.url_helpers
75
+ end
76
+ end
77
+ end