auth_three 0.1.1
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/MIT-LICENSE +20 -0
- data/README.md +44 -0
- data/Rakefile +33 -0
- data/lib/auth_three/version.rb +3 -0
- data/lib/auth_three.rb +10 -0
- data/lib/generators/controller_helpers.rb +147 -0
- data/lib/generators/install_generator.rb +109 -0
- data/lib/generators/orm_helpers.rb +96 -0
- data/lib/tasks/auth_three_tasks.rake +4 -0
- data/lib/templates/README.md +19 -0
- data/lib/templates/html_controllers/application_controller.rb +42 -0
- data/lib/templates/json_controllers/application_controller.rb +42 -0
- data/lib/templates/user.rb +50 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4963b95a4a2af52430d8fd08e5326114dd16c119
|
4
|
+
data.tar.gz: d2d693276a15bc58ba76244e437af622210a63a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f55db84bea441008016308734d9dcb8bc5737aed7e9a8a97f4d26faec40f47012dadbc4add90160d8ad12275798ea999fceffa9ec54861f893d81614716951c5
|
7
|
+
data.tar.gz: 286250c6d441e0aafe3d1b1010eaf0534c6af327307d46034504983e2809264180072a78a292eae874be24aba67f6b7b59e0b62e7eeb73d2618a503bf6b892f9
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 Michael Chilton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# AuthThree
|
2
|
+
This is a small gem that will generate the necessary files and configuration for
|
3
|
+
a simple, effective authentication pattern.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
After installation, run `rails g auth_three:install`, and the generator will
|
7
|
+
separate the appropriate files and run the necessary database migrations.
|
8
|
+
|
9
|
+
There is also a setting for controller namespacing, which is intended to make namespaced api
|
10
|
+
controllers and routes. Add a `--namespace=api` argument to your generation command to generate
|
11
|
+
namespaced controllers and routes. Note, this option is intended to be used to make namespaced
|
12
|
+
api controllers, and so will output controller files and routes that by default will respond with JSON.
|
13
|
+
All output may be modified later.
|
14
|
+
|
15
|
+
This pattern requires BCrypt for securing passwords. Be sure to have it in your Gemfile and run `bundle install` if necessary.
|
16
|
+
|
17
|
+
A database is required to use this pattern and run the generator. Be sure to run bundle exec rake db:create
|
18
|
+
if one does not yet exist.
|
19
|
+
|
20
|
+
|
21
|
+
*It is recommended to run this generator at the start of a project to avoid conflicts with other content already present.*
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
gem 'auth_three'
|
28
|
+
```
|
29
|
+
|
30
|
+
And then execute:
|
31
|
+
```bash
|
32
|
+
$ bundle
|
33
|
+
```
|
34
|
+
|
35
|
+
Or install it yourself as:
|
36
|
+
```bash
|
37
|
+
$ gem install auth_three
|
38
|
+
```
|
39
|
+
|
40
|
+
## Contributing
|
41
|
+
Contributions are always welcome.
|
42
|
+
|
43
|
+
## License
|
44
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'AuthThree'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
require 'bundler/gem_tasks'
|
23
|
+
|
24
|
+
require 'rake/testtask'
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << 'test'
|
28
|
+
t.pattern = 'test/**/*_test.rb'
|
29
|
+
t.verbose = false
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task default: :test
|
data/lib/auth_three.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
module AuthThree
|
2
|
+
module Generators
|
3
|
+
module ControllerHelpers
|
4
|
+
def users_controller_contents
|
5
|
+
<<RUBY
|
6
|
+
def show
|
7
|
+
@user = User.find(params[:id])
|
8
|
+
render :show
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@user = User.new
|
13
|
+
render :new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
@user = User.new(user_params)
|
18
|
+
|
19
|
+
if @user.save
|
20
|
+
sign_in(@user)
|
21
|
+
redirect_to links_url
|
22
|
+
else
|
23
|
+
flash.now[:errors] = @user.errors.full_messages
|
24
|
+
render :new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def edit
|
29
|
+
@user = User.find(params[:id])
|
30
|
+
render :edit
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
@user = User.find(params[:id])
|
35
|
+
if @user.update
|
36
|
+
# default will redirect to root_url, change as you wish
|
37
|
+
redirect_to root_url
|
38
|
+
else
|
39
|
+
flash.now[:errors] = @user.errors.full_messages
|
40
|
+
render :edit
|
41
|
+
end
|
42
|
+
end
|
43
|
+
RUBY
|
44
|
+
end
|
45
|
+
|
46
|
+
def sessions_controller_contents
|
47
|
+
<<RUBY
|
48
|
+
def new
|
49
|
+
render :new
|
50
|
+
end
|
51
|
+
|
52
|
+
def create
|
53
|
+
user = User.find_by_credentials(
|
54
|
+
params[:user][:username],
|
55
|
+
params[:user][:password]
|
56
|
+
)
|
57
|
+
|
58
|
+
if user
|
59
|
+
login!(user)
|
60
|
+
# requires root_url to be set in routes.rb
|
61
|
+
redirect_to root_url
|
62
|
+
else
|
63
|
+
flash.now[:errors] = ["Invalid username or password"]
|
64
|
+
render :new
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def destroy
|
69
|
+
logout!
|
70
|
+
redirect_to new_session_url
|
71
|
+
end
|
72
|
+
RUBY
|
73
|
+
end
|
74
|
+
|
75
|
+
def namespace_sessions_contents(namespace_label)
|
76
|
+
<<RUBY
|
77
|
+
def create
|
78
|
+
@user = User.find_by_credentials(
|
79
|
+
params[:user][:username],
|
80
|
+
params[:user][:password]
|
81
|
+
)
|
82
|
+
|
83
|
+
if @user
|
84
|
+
login!(@user)
|
85
|
+
render :"#{namespace_label}/users/show"
|
86
|
+
else
|
87
|
+
render(json: ['Sorry, you entered an incorrect email address or password.'], status: 401)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def destroy
|
92
|
+
@user = current_user
|
93
|
+
if @user
|
94
|
+
logout!
|
95
|
+
render json: @user
|
96
|
+
else
|
97
|
+
render(json: ["You are not signed in"], status: 404)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
RUBY
|
101
|
+
end
|
102
|
+
|
103
|
+
def namespace_users_contents(namespace_label)
|
104
|
+
<<RUBY
|
105
|
+
def create
|
106
|
+
@user = User.new(user_params)
|
107
|
+
if @user.save
|
108
|
+
login!(@user)
|
109
|
+
render :show
|
110
|
+
else
|
111
|
+
errors = @user.errors.full_messages
|
112
|
+
render(json: errors, status: 422)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def show
|
117
|
+
@user = User.find(params[:id])
|
118
|
+
render :show
|
119
|
+
end
|
120
|
+
|
121
|
+
def update
|
122
|
+
@user = User.find(params[:user][:id])
|
123
|
+
if @user.update(user_params)
|
124
|
+
render :show
|
125
|
+
else
|
126
|
+
errors = @user.errors.full_messages
|
127
|
+
render(json: errors, status: 422)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
RUBY
|
131
|
+
end
|
132
|
+
|
133
|
+
def router_contents(namespace_label)
|
134
|
+
<<-RUBY
|
135
|
+
|
136
|
+
namespace :#{namespace_label}, defaults: {format: :json} do
|
137
|
+
resources :users
|
138
|
+
end
|
139
|
+
namespace :#{namespace_label}, defaults: {format: :json} do
|
140
|
+
resource :session
|
141
|
+
end
|
142
|
+
RUBY
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module AuthThree
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include AuthThree::Generators::OrmHelpers
|
5
|
+
include AuthThree::Generators::ControllerHelpers
|
6
|
+
source_root File.expand_path("../../templates", __FILE__)
|
7
|
+
class_option :namespace, type: :string, description: "Namespace your controllers"
|
8
|
+
|
9
|
+
def generate_db_content
|
10
|
+
invoke "active_record:model", ['user'], migration: true
|
11
|
+
end
|
12
|
+
|
13
|
+
def inject_create_users_migration_content
|
14
|
+
content = migration_data
|
15
|
+
indent_depth = 0
|
16
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
17
|
+
index_content = migration_index_data
|
18
|
+
require create_users_migration_file
|
19
|
+
insert_into_file(create_users_migration_file, content, after: ":users do |t|\n")
|
20
|
+
insert_into_file(create_users_migration_file, index_content, after: "t.timestamps\n end")
|
21
|
+
end
|
22
|
+
|
23
|
+
def migrate_users_data
|
24
|
+
rake "db:migrate"
|
25
|
+
end
|
26
|
+
|
27
|
+
def inject_user_model_content
|
28
|
+
content = model_contents
|
29
|
+
|
30
|
+
indent_depth = 0
|
31
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
32
|
+
|
33
|
+
inject_into_class("#{model_path}/user.rb", User, content)
|
34
|
+
end
|
35
|
+
|
36
|
+
def copy_application_controller
|
37
|
+
copy_file(controller_source("application_controller.rb"), "#{File.join("app", "controllers")}/application_controller.rb", force: true)
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_user_controllers
|
41
|
+
controller_names = ['users', 'sessions']
|
42
|
+
controller_names.each do |name|
|
43
|
+
if options[:namespace]
|
44
|
+
generate "controller", "#{options[:namespace]}/#{name} --no-helper --no-assets"
|
45
|
+
content = send("namespace_#{name}_contents".to_sym, options[:namespace])
|
46
|
+
indent_depth = 0
|
47
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
48
|
+
inject_into_class("#{controllers_path}/#{name}_controller.rb", ("#{options[:namespace]}::".camelcase + "#{name}_controller".camelcase).constantize, content)
|
49
|
+
else
|
50
|
+
generate "controller", "#{name} --no-helper --no-assets"
|
51
|
+
content = send("#{name}_controller_contents".to_sym)
|
52
|
+
indent_depth = 0
|
53
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
54
|
+
inject_into_class("#{controllers_path}/#{name}_controller.rb", "#{name}_controller".camelcase.constantize, content)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_routes
|
60
|
+
if options[:namespace]
|
61
|
+
content = router_contents(options[:namespace])
|
62
|
+
indent_depth = 0
|
63
|
+
content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
|
64
|
+
|
65
|
+
route(content)
|
66
|
+
else
|
67
|
+
route "resources :users"
|
68
|
+
route "resource :session"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
def further_instructions
|
74
|
+
readme "README.md"
|
75
|
+
end
|
76
|
+
private
|
77
|
+
|
78
|
+
def controllers_path
|
79
|
+
if options[:namespace]
|
80
|
+
File.join("app", "controllers", "#{options[:namespace]}")
|
81
|
+
else
|
82
|
+
File.join("app", "controllers")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def controller_source(controller_name)
|
87
|
+
if options[:namespace]
|
88
|
+
File.expand_path("../../templates/json_controllers/#{controller_name}", __FILE__)
|
89
|
+
else
|
90
|
+
File.expand_path("../../templates/html_controllers/#{controller_name}", __FILE__)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def migration_path
|
95
|
+
@migration_path ||= File.join("db", "migrate")
|
96
|
+
end
|
97
|
+
|
98
|
+
def create_users_migration_file
|
99
|
+
Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_create_users.rb$/).first
|
100
|
+
end
|
101
|
+
|
102
|
+
def model_path
|
103
|
+
@model_path ||= File.join("app", "models")
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module AuthThree
|
2
|
+
module Generators
|
3
|
+
module OrmHelpers
|
4
|
+
|
5
|
+
def model_contents
|
6
|
+
<<RUBY
|
7
|
+
validates :username, :email, :session_token, presence: true
|
8
|
+
validates :username, uniqueness: true
|
9
|
+
validates :password_digest, presence: { message: "Password can't be blank."}
|
10
|
+
validates :password, length: { minimum: 6, allow_nil: true }
|
11
|
+
|
12
|
+
after_initialize :ensure_session_token
|
13
|
+
|
14
|
+
def self.token
|
15
|
+
SecureRandom::urlsafe_base64(16)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.find_by_credentials(username, password)
|
19
|
+
user = User.find_by(username: username)
|
20
|
+
return nil if user.nil?
|
21
|
+
if user.is_password?(password)
|
22
|
+
return user
|
23
|
+
else
|
24
|
+
return nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :password
|
29
|
+
|
30
|
+
def password=(password)
|
31
|
+
@password = password
|
32
|
+
self.password_digest = digest(password)
|
33
|
+
end
|
34
|
+
|
35
|
+
def digest(string)
|
36
|
+
string_digest = BCrypt::Password.create(string)
|
37
|
+
end
|
38
|
+
|
39
|
+
def is_password?(password)
|
40
|
+
BCrypt::Password.new(self.password_digest).is_password?(password)
|
41
|
+
end
|
42
|
+
|
43
|
+
def reset_session_token!
|
44
|
+
self.session_token = User.token
|
45
|
+
self.save
|
46
|
+
self.session_token
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def ensure_session_token
|
52
|
+
self.session_token ||= User.token
|
53
|
+
end
|
54
|
+
RUBY
|
55
|
+
end
|
56
|
+
|
57
|
+
def migration_data
|
58
|
+
<<RUBY
|
59
|
+
t.string :username, null: false
|
60
|
+
|
61
|
+
t.string :email, null: false
|
62
|
+
|
63
|
+
t.string :password_digest, null: false
|
64
|
+
t.string :session_token, null: false
|
65
|
+
RUBY
|
66
|
+
end
|
67
|
+
|
68
|
+
def migration_index_data
|
69
|
+
<<RUBY
|
70
|
+
|
71
|
+
add_index :users, :username, unique: true
|
72
|
+
add_index :users, :email, unique: true
|
73
|
+
add_index :users, :session_token, unique: true
|
74
|
+
RUBY
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def model_exists?
|
80
|
+
File.exist?(File.join(destination_root, model_path))
|
81
|
+
end
|
82
|
+
|
83
|
+
def migration_exists?(table_name)
|
84
|
+
Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_create_users.rb$/).first
|
85
|
+
end
|
86
|
+
|
87
|
+
def migration_path
|
88
|
+
@migration_path ||= File.join("db", "migrate")
|
89
|
+
end
|
90
|
+
|
91
|
+
def model_path
|
92
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
===============================================================================
|
2
|
+
|
3
|
+
Some setup you must do manually if you haven't yet:
|
4
|
+
|
5
|
+
1. This authentication pattern depends on the BCrypt library for securing
|
6
|
+
passwords. If you have not done so already, uncomment or add in
|
7
|
+
|
8
|
+
gem 'bcrypt'
|
9
|
+
|
10
|
+
and then run
|
11
|
+
|
12
|
+
bundle install
|
13
|
+
|
14
|
+
2. Ensure you have defined root_url to *something* in your config/routes.rb.
|
15
|
+
For example:
|
16
|
+
|
17
|
+
root to: "home#index"
|
18
|
+
|
19
|
+
===============================================================================
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
protect_from_forgery with: :exception
|
3
|
+
|
4
|
+
helper_method :current_user, :logged_in?
|
5
|
+
|
6
|
+
def current_user
|
7
|
+
@current_user ||= User.find_by(session_token: session[:session_token])
|
8
|
+
end
|
9
|
+
|
10
|
+
def login!(user)
|
11
|
+
@current_user = user
|
12
|
+
session[:session_token] = user.reset_session_token!
|
13
|
+
end
|
14
|
+
|
15
|
+
def logout!
|
16
|
+
current_user.reset_session_token!
|
17
|
+
session[:session_token] = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def logged_in?
|
21
|
+
!!current_user
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def require_logged_in
|
27
|
+
unless logged_in?
|
28
|
+
redirect_to new_session_url
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def require_logged_out
|
33
|
+
if logged_in?
|
34
|
+
# redirect to a root of your choosing if users are in a place that should
|
35
|
+
# not be accessible when logged in
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def user_params
|
40
|
+
params.require(:user).permit(:username, :password, :email)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
protect_from_forgery with: :exception
|
3
|
+
|
4
|
+
helper_method :current_user, :logged_in?
|
5
|
+
|
6
|
+
def current_user
|
7
|
+
@current_user ||= User.find_by(session_token: session[:session_token])
|
8
|
+
end
|
9
|
+
|
10
|
+
def login!(user)
|
11
|
+
@current_user = user
|
12
|
+
session[:session_token] = user.reset_session_token!
|
13
|
+
end
|
14
|
+
|
15
|
+
def logout!
|
16
|
+
current_user.reset_session_token!
|
17
|
+
session[:session_token] = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def logged_in?
|
21
|
+
!!current_user
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def require_logged_in
|
27
|
+
unless logged_in?
|
28
|
+
render json: { errors: ['Not signed in.'] }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def require_logged_out
|
33
|
+
if logged_in?
|
34
|
+
# redirect to a root of your choosing if users are in a place that should
|
35
|
+
# not be accessible when logged in
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def user_params
|
40
|
+
params.require(:user).permit(:username, :password, :email)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class User < ApplicationRecord
|
2
|
+
validates :username, :email, :session_token, presence: true
|
3
|
+
validates :username, uniqueness: true
|
4
|
+
validates :password_digest, presence: { message: "Password can't be blank."}
|
5
|
+
validates :password, length: { minimum: 6, allow_nil: true }
|
6
|
+
|
7
|
+
after_initialize :ensure_session_token
|
8
|
+
|
9
|
+
def self.token
|
10
|
+
SecureRandom::urlsafe_base64(16)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find_by_credentials(username, password)
|
14
|
+
user = User.find_by(username: username)
|
15
|
+
return nil if user.nil?
|
16
|
+
if user.is_password?(password)
|
17
|
+
return user
|
18
|
+
else
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :password
|
24
|
+
|
25
|
+
def password=(password)
|
26
|
+
@password = password
|
27
|
+
self.password_digest = digest(password)
|
28
|
+
end
|
29
|
+
|
30
|
+
def digest(string)
|
31
|
+
string_digest = BCrypt::Password.create(string)
|
32
|
+
end
|
33
|
+
|
34
|
+
def is_password?(password)
|
35
|
+
BCrypt::Password.new(self.password_digest).is_password?(password)
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset_session_token!
|
39
|
+
self.session_token = User.token
|
40
|
+
self.save
|
41
|
+
self.session_token
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def ensure_session_token
|
47
|
+
self.session_token ||= User.token
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auth_three
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Chilton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-05-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pg
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Automate basic authentication for your coding challenges
|
84
|
+
email:
|
85
|
+
- michaelc962@yahoo.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- MIT-LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/auth_three.rb
|
94
|
+
- lib/auth_three/version.rb
|
95
|
+
- lib/generators/controller_helpers.rb
|
96
|
+
- lib/generators/install_generator.rb
|
97
|
+
- lib/generators/orm_helpers.rb
|
98
|
+
- lib/tasks/auth_three_tasks.rake
|
99
|
+
- lib/templates/README.md
|
100
|
+
- lib/templates/html_controllers/application_controller.rb
|
101
|
+
- lib/templates/json_controllers/application_controller.rb
|
102
|
+
- lib/templates/user.rb
|
103
|
+
homepage: https://github.com/mc962/auth_three
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.5.2
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Automation for a basic authentication pattern
|
127
|
+
test_files: []
|