rails_mvp_authentication 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/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/rails_mvp_authentication_manifest.js +1 -0
- data/app/assets/stylesheets/rails_mvp_authentication/application.css +15 -0
- data/app/controllers/rails_mvp_authentication/application_controller.rb +4 -0
- data/app/helpers/rails_mvp_authentication/application_helper.rb +4 -0
- data/app/jobs/rails_mvp_authentication/application_job.rb +4 -0
- data/app/mailers/rails_mvp_authentication/application_mailer.rb +6 -0
- data/app/models/rails_mvp_authentication/application_record.rb +5 -0
- data/app/views/layouts/rails_mvp_authentication/application.html.erb +15 -0
- data/config/routes.rb +2 -0
- data/lib/generators/rails_mvp_authentication/USAGE +5 -0
- data/lib/generators/rails_mvp_authentication/install_generator.rb +251 -0
- data/lib/generators/rails_mvp_authentication/templates/README +7 -0
- data/lib/generators/rails_mvp_authentication/templates/authentication.rb.tt +58 -0
- data/lib/generators/rails_mvp_authentication/templates/confirmations_controller.rb.tt +32 -0
- data/lib/generators/rails_mvp_authentication/templates/current.rb.tt +3 -0
- data/lib/generators/rails_mvp_authentication/templates/passwords_controller.rb.tt +52 -0
- data/lib/generators/rails_mvp_authentication/templates/sessions_controller.rb.tt +30 -0
- data/lib/generators/rails_mvp_authentication/templates/test/controllers/active_sessions_controller_test.rb.tt +68 -0
- data/lib/generators/rails_mvp_authentication/templates/test/controllers/confirmations_controller_test.rb.tt +143 -0
- data/lib/generators/rails_mvp_authentication/templates/test/controllers/passwords_controller_test.rb.tt +119 -0
- data/lib/generators/rails_mvp_authentication/templates/test/controllers/sessions_controller_test.rb.tt +105 -0
- data/lib/generators/rails_mvp_authentication/templates/test/controllers/users_controller_test.rb.tt +150 -0
- data/lib/generators/rails_mvp_authentication/templates/test/integration/friendly_redirects_test.rb.tt +23 -0
- data/lib/generators/rails_mvp_authentication/templates/test/integration/user_interface_test.rb.tt +35 -0
- data/lib/generators/rails_mvp_authentication/templates/test/mailers/previews/user_mailer_preview.rb.tt +17 -0
- data/lib/generators/rails_mvp_authentication/templates/test/mailers/user_mailer_test.rb.tt +25 -0
- data/lib/generators/rails_mvp_authentication/templates/test/models/active_session_test.rb.tt +18 -0
- data/lib/generators/rails_mvp_authentication/templates/test/models/user_test.rb.tt +183 -0
- data/lib/generators/rails_mvp_authentication/templates/test/system/logins_test.rb.tt +18 -0
- data/lib/generators/rails_mvp_authentication/templates/user.rb.tt +96 -0
- data/lib/generators/rails_mvp_authentication/templates/user_mailer.rb.tt +22 -0
- data/lib/generators/rails_mvp_authentication/templates/users_controller.rb.tt +59 -0
- data/lib/generators/rails_mvp_authentication/templates/views/confirmations/new.html.erb.tt +4 -0
- data/lib/generators/rails_mvp_authentication/templates/views/passwords/edit.html.erb.tt +11 -0
- data/lib/generators/rails_mvp_authentication/templates/views/passwords/new.html.erb.tt +4 -0
- data/lib/generators/rails_mvp_authentication/templates/views/sessions/new.html.erb.tt +15 -0
- data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.html.erb.tt +3 -0
- data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.text.erb.tt +3 -0
- data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.html.erb.tt +3 -0
- data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.text.erb.tt +3 -0
- data/lib/generators/rails_mvp_authentication/templates/views/users/edit.html.erb.tt +42 -0
- data/lib/generators/rails_mvp_authentication/templates/views/users/new.html.erb.tt +16 -0
- data/lib/rails_mvp_authentication/engine.rb +5 -0
- data/lib/rails_mvp_authentication/version.rb +3 -0
- data/lib/rails_mvp_authentication.rb +6 -0
- data/lib/tasks/rails_mvp_authentication_tasks.rake +4 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4fa3c307eee6e61d01e318fe1453a30660e18f0e2eb1de7b725c22f93c6a60e6
|
4
|
+
data.tar.gz: 8ac56c76c7dd2f316ef9b19c81e8c78987cade71cee289f2e1b3ef8c1dc22d0e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: da4f0c62616acff46d67f8ca95ae1b7606710a23e99dfab4b6225b24ab90dca5dab8aec39c64d5749d4b608a21a9ea6ed3891f7ecb5586c8b568b3d71f394bfc
|
7
|
+
data.tar.gz: c6a117f9c7f8cb7168087329e21a62636b2b8bb74561f28e77dcb5ce8052f5add760b3254f43dfd051cfd8198103f57703d364c547134edcb0d8706365db0c94
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 Steve Polito
|
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,28 @@
|
|
1
|
+
# RailsMvpAuthentication
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "rails_mvp_authentication"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install rails_mvp_authentication
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/rails_mvp_authentication .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Rails mvp authentication</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag "rails_mvp_authentication/application", media: "all" %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
|
12
|
+
<%= yield %>
|
13
|
+
|
14
|
+
</body>
|
15
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
module RailsMvpAuthentication
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
desc "Rails authentication via a generator."
|
7
|
+
|
8
|
+
def perform
|
9
|
+
create_users_table
|
10
|
+
modify_users_table
|
11
|
+
create_user_model
|
12
|
+
add_bcrypt
|
13
|
+
add_routes
|
14
|
+
create_current_model
|
15
|
+
create_users_controller
|
16
|
+
create_user_views
|
17
|
+
create_confirmations_controller
|
18
|
+
create_confirmation_views
|
19
|
+
ceate_user_mailer
|
20
|
+
ceate_user_mailer_views
|
21
|
+
configure_hosts
|
22
|
+
create_authentication_concern
|
23
|
+
modify_application_controller
|
24
|
+
create_sessions_controller
|
25
|
+
create_session_views
|
26
|
+
create_passwords_controller
|
27
|
+
create_password_views
|
28
|
+
if using_default_test_suite
|
29
|
+
create_tests
|
30
|
+
modify_test_helper
|
31
|
+
end
|
32
|
+
add_links
|
33
|
+
print_instructions
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def add_bcrypt
|
39
|
+
return unless gemfile_exists
|
40
|
+
|
41
|
+
if bcrypt_is_commented_out
|
42
|
+
uncomment_lines(gemfile, /gem "bcrypt", "~> 3.1.7"/)
|
43
|
+
else
|
44
|
+
gem "bcrypt", "~> 3.1.7"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_links
|
49
|
+
inject_into_file "app/views/layouts/application.html.erb", after: "<body>\n" do
|
50
|
+
<<-ERB
|
51
|
+
<ul>
|
52
|
+
<% if user_signed_in? %>
|
53
|
+
<li><%= link_to "My Acount", account_path %></li>
|
54
|
+
<li><%= button_to "Logout", logout_path, method: :delete %></li>
|
55
|
+
<% else %>
|
56
|
+
<li><%= link_to "Login", login_path %></li>
|
57
|
+
<li><%= link_to "Sign Up", sign_up_path %></li>
|
58
|
+
<li><%= link_to "Forgot my password", new_password_path %></li>
|
59
|
+
<li><%= link_to "Didn't receive confirmation instructions", new_confirmation_path %></li>
|
60
|
+
<% end %>
|
61
|
+
</ul>
|
62
|
+
ERB
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_routes
|
67
|
+
route %(
|
68
|
+
post "sign_up", to: "users#create"
|
69
|
+
get "sign_up", to: "users#new"
|
70
|
+
put "account", to: "users#update"
|
71
|
+
get "account", to: "users#edit"
|
72
|
+
delete "account", to: "users#destroy"
|
73
|
+
resources :confirmations, only: [:create, :edit, :new], param: :confirmation_token
|
74
|
+
post "login", to: "sessions#create"
|
75
|
+
delete "logout", to: "sessions#destroy"
|
76
|
+
get "login", to: "sessions#new"
|
77
|
+
resources :passwords, only: [:create, :edit, :new, :update], param: :password_reset_token
|
78
|
+
resources :active_sessions, only: [:destroy] do
|
79
|
+
collection do
|
80
|
+
delete "destroy_all"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def bcrypt_is_commented_out
|
87
|
+
gemfile = path_to("Gemfile")
|
88
|
+
|
89
|
+
File.open(gemfile).each_line do |line|
|
90
|
+
return true if line == '# gem "bcrypt", "~> 3.1.7"'
|
91
|
+
end
|
92
|
+
|
93
|
+
false
|
94
|
+
end
|
95
|
+
|
96
|
+
def configure_hosts
|
97
|
+
application(nil, env: "test") do
|
98
|
+
'config.action_mailer.default_url_options = {host: "example.com"}'
|
99
|
+
end
|
100
|
+
application(nil, env: "development") do
|
101
|
+
'config.action_mailer.default_url_options = {host: "localhost", port: 3000}'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_authentication_concern
|
106
|
+
template "authentication.rb", "app/controllers/concerns/authentication.rb"
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_confirmations_controller
|
110
|
+
template "confirmations_controller.rb", "app/controllers/confirmations_controller.rb"
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_confirmation_views
|
114
|
+
template "views/confirmations/new.html.erb", "app/views/confirmations/new.html.erb"
|
115
|
+
end
|
116
|
+
|
117
|
+
def create_current_model
|
118
|
+
template "current.rb", "app/models/current.rb"
|
119
|
+
end
|
120
|
+
|
121
|
+
def create_passwords_controller
|
122
|
+
template "passwords_controller.rb", "app/controllers/passwords_controller.rb"
|
123
|
+
end
|
124
|
+
|
125
|
+
def create_password_views
|
126
|
+
template "views/passwords/new.html.erb", "app/views/passwords/new.html.erb"
|
127
|
+
template "views/passwords/edit.html.erb", "app/views/passwords/edit.html.erb"
|
128
|
+
end
|
129
|
+
|
130
|
+
def create_sessions_controller
|
131
|
+
template "sessions_controller.rb", "app/controllers/sessions_controller.rb"
|
132
|
+
end
|
133
|
+
|
134
|
+
def create_session_views
|
135
|
+
template "views/sessions/new.html.erb", "app/views/sessions/new.html.erb"
|
136
|
+
end
|
137
|
+
|
138
|
+
def create_users_controller
|
139
|
+
template "users_controller.rb", "app/controllers/users_controller.rb"
|
140
|
+
end
|
141
|
+
|
142
|
+
def create_tests
|
143
|
+
template "test/controllers/active_sessions_controller_test.rb", "test/controllers/active_sessions_controller_test.rb"
|
144
|
+
template "test/controllers/confirmations_controller_test.rb", "test/controllers/confirmations_controller_test.rb"
|
145
|
+
template "test/controllers/active_sessions_controller_test.rb", "test/controllers/active_sessions_controller_test.rb"
|
146
|
+
template "test/controllers/passwords_controller_test.rb", "test/controllers/passwords_controller_test.rb"
|
147
|
+
template "test/controllers/sessions_controller_test.rb", "test/controllers/sessions_controller_test.rb"
|
148
|
+
template "test/controllers/users_controller_test.rb", "test/controllers/users_controller_test.rb"
|
149
|
+
|
150
|
+
template "test/integration/friendly_redirects_test.rb", "test/integration/friendly_redirects_test.rb"
|
151
|
+
template "test/integration/user_interface_test.rb", "test/integration/user_interface_test.rb"
|
152
|
+
|
153
|
+
template "test/mailers/previews/user_mailer_preview.rb", "test/mailers/previews/user_mailer_preview.rb"
|
154
|
+
template "test/mailers/user_mailer_test.rb", "test/mailers/user_mailer_test.rb"
|
155
|
+
|
156
|
+
template "test/models/user_test.rb", "test/models/user_test.rb"
|
157
|
+
template "test/models/active_session_test.rb", "test/models/active_session_test.rb"
|
158
|
+
|
159
|
+
template "test/system/logins_test.rb", "test/system/logins_test.rb"
|
160
|
+
end
|
161
|
+
|
162
|
+
def ceate_user_mailer
|
163
|
+
template "user_mailer.rb", "app/mailers/user_mailer.rb"
|
164
|
+
end
|
165
|
+
|
166
|
+
def ceate_user_mailer_views
|
167
|
+
template "views/user_mailer/confirmation.html.erb", "app/views/user_mailer/confirmation.html.erb"
|
168
|
+
template "views/user_mailer/confirmation.text.erb", "app/views/user_mailer/confirmation.text.erb"
|
169
|
+
template "views/user_mailer/password_reset.html.erb", "app/views/user_mailer/password_reset.html.erb"
|
170
|
+
template "views/user_mailer/password_reset.text.erb", "app/views/user_mailer/password_reset.text.erb"
|
171
|
+
end
|
172
|
+
|
173
|
+
def create_user_model
|
174
|
+
template "user.rb", "app/models/user.rb"
|
175
|
+
end
|
176
|
+
|
177
|
+
def create_users_table
|
178
|
+
generate "migration", "create_users_table email:string:index confirmed_at:datetime password_digest:string unconfirmed_email:string"
|
179
|
+
end
|
180
|
+
|
181
|
+
def create_user_views
|
182
|
+
template "views/users/edit.html.erb", "app/views/users/edit.html.erb"
|
183
|
+
template "views/users/new.html.erb", "app/views/users/new.html.erb"
|
184
|
+
end
|
185
|
+
|
186
|
+
def directory_exists(directory)
|
187
|
+
File.directory?(directory)
|
188
|
+
end
|
189
|
+
|
190
|
+
def gemfile
|
191
|
+
path_to("Gemfile")
|
192
|
+
end
|
193
|
+
|
194
|
+
def gemfile_exists
|
195
|
+
File.exist?(gemfile)
|
196
|
+
end
|
197
|
+
|
198
|
+
def modify_application_controller
|
199
|
+
inject_into_file "app/controllers/application_controller.rb", "\tinclude Authentication\n", after: "class ApplicationController < ActionController::Base\n"
|
200
|
+
end
|
201
|
+
|
202
|
+
def modify_test_helper
|
203
|
+
inject_into_class "test/test_helper.rb", "ActiveSupport::TestCase" do
|
204
|
+
<<-RUBY
|
205
|
+
def current_user
|
206
|
+
if session[:current_active_session_id].present?
|
207
|
+
ActiveSession.find_by(id: session[:current_active_session_id])&.user
|
208
|
+
else
|
209
|
+
cookies[:remember_token].present?
|
210
|
+
ActiveSession.find_by(remember_token: cookies[:remember_token])&.user
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def login(user, remember_user: nil)
|
215
|
+
post login_path, params: {
|
216
|
+
user: {
|
217
|
+
email: user.email,
|
218
|
+
password: user.password,
|
219
|
+
remember_me: remember_user == true ? 1 : 0
|
220
|
+
}
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
def logout
|
225
|
+
session.delete(:current_active_session_id)
|
226
|
+
end
|
227
|
+
RUBY
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def modify_users_table
|
232
|
+
migration = Dir.glob(Rails.root.join("db/migrate/*")).max_by { |f| File.mtime(f) }
|
233
|
+
gsub_file migration, /t.string :email/, "t.string :email, null: false"
|
234
|
+
gsub_file migration, /t.string :password_digest/, "t.string :password_digest, null: false"
|
235
|
+
gsub_file migration, /add_index :users_tables, :email/, "add_index :users_tables, :email, unique: true"
|
236
|
+
end
|
237
|
+
|
238
|
+
def path_to(path)
|
239
|
+
Rails.root.join(path)
|
240
|
+
end
|
241
|
+
|
242
|
+
def print_instructions
|
243
|
+
readme "README"
|
244
|
+
end
|
245
|
+
|
246
|
+
def using_default_test_suite
|
247
|
+
directory_exists(path_to("test"))
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Authentication
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_action :current_user
|
6
|
+
helper_method :current_user
|
7
|
+
helper_method :user_signed_in?
|
8
|
+
end
|
9
|
+
|
10
|
+
def authenticate_user!
|
11
|
+
store_location
|
12
|
+
redirect_to login_path, alert: "You need to login to access that page." unless user_signed_in?
|
13
|
+
end
|
14
|
+
|
15
|
+
def login(user)
|
16
|
+
reset_session
|
17
|
+
active_session = user.active_sessions.create!(user_agent: request.user_agent, ip_address: request.ip)
|
18
|
+
session[:current_active_session_id] = active_session.id
|
19
|
+
|
20
|
+
active_session
|
21
|
+
end
|
22
|
+
|
23
|
+
def forget_active_session
|
24
|
+
cookies.delete :remember_token
|
25
|
+
end
|
26
|
+
|
27
|
+
def logout
|
28
|
+
active_session = ActiveSession.find_by(id: session[:current_active_session_id])
|
29
|
+
reset_session
|
30
|
+
active_session.destroy! if active_session.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
def redirect_if_authenticated
|
34
|
+
redirect_to root_path, alert: "You are already logged in." if user_signed_in?
|
35
|
+
end
|
36
|
+
|
37
|
+
def remember(active_session)
|
38
|
+
cookies.permanent.encrypted[:remember_token] = active_session.remember_token
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def current_user
|
44
|
+
Current.user = if session[:current_active_session_id].present?
|
45
|
+
ActiveSession.find_by(id: session[:current_active_session_id])&.user
|
46
|
+
elsif cookies.permanent.encrypted[:remember_token].present?
|
47
|
+
ActiveSession.find_by(remember_token: cookies.permanent.encrypted[:remember_token])&.user
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def user_signed_in?
|
52
|
+
Current.user.present?
|
53
|
+
end
|
54
|
+
|
55
|
+
def store_location
|
56
|
+
session[:user_return_to] = request.original_url if request.get? && request.local?
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class ConfirmationsController < ApplicationController
|
2
|
+
before_action :redirect_if_authenticated, only: [:create, :new]
|
3
|
+
|
4
|
+
def create
|
5
|
+
@user = User.find_by(email: params[:user][:email].downcase)
|
6
|
+
|
7
|
+
if @user.present? && @user.unconfirmed?
|
8
|
+
@user.send_confirmation_email!
|
9
|
+
redirect_to root_path, notice: "Check your email for confirmation instructions."
|
10
|
+
else
|
11
|
+
redirect_to new_confirmation_path, alert: "We could not find a user with that email or that email has already been confirmed."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def edit
|
16
|
+
@user = User.find_signed(params[:confirmation_token], purpose: :confirm_email)
|
17
|
+
if @user.present? && @user.unconfirmed_or_reconfirming?
|
18
|
+
if @user.confirm!
|
19
|
+
login @user
|
20
|
+
redirect_to root_path, notice: "Your account has been confirmed."
|
21
|
+
else
|
22
|
+
redirect_to new_confirmation_path, alert: "Something went wrong."
|
23
|
+
end
|
24
|
+
else
|
25
|
+
redirect_to new_confirmation_path, alert: "Invalid token."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def new
|
30
|
+
@user = User.new
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class PasswordsController < ApplicationController
|
2
|
+
before_action :redirect_if_authenticated
|
3
|
+
|
4
|
+
def create
|
5
|
+
@user = User.find_by(email: params[:user][:email].downcase)
|
6
|
+
if @user.present?
|
7
|
+
if @user.confirmed?
|
8
|
+
@user.send_password_reset_email!
|
9
|
+
redirect_to root_path, notice: "If that user exists we've sent instructions to their email."
|
10
|
+
else
|
11
|
+
redirect_to new_confirmation_path, alert: "Please confirm your email first."
|
12
|
+
end
|
13
|
+
else
|
14
|
+
redirect_to root_path, notice: "If that user exists we've sent instructions to their email."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def edit
|
19
|
+
@user = User.find_signed(params[:password_reset_token], purpose: :reset_password)
|
20
|
+
if @user.present? && @user.unconfirmed?
|
21
|
+
redirect_to new_confirmation_path, alert: "You must confirm your email before you can sign in."
|
22
|
+
elsif @user.nil?
|
23
|
+
redirect_to new_password_path, alert: "Invalid or expired token."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def new
|
28
|
+
end
|
29
|
+
|
30
|
+
def update
|
31
|
+
@user = User.find_signed(params[:password_reset_token], purpose: :reset_password)
|
32
|
+
if @user
|
33
|
+
if @user.unconfirmed?
|
34
|
+
redirect_to new_confirmation_path, alert: "You must confirm your email before you can sign in."
|
35
|
+
elsif @user.update(password_params)
|
36
|
+
redirect_to login_path, notice: "Sign in."
|
37
|
+
else
|
38
|
+
flash.now[:alert] = @user.errors.full_messages.to_sentence
|
39
|
+
render :edit, status: :unprocessable_entity
|
40
|
+
end
|
41
|
+
else
|
42
|
+
flash.now[:alert] = "Invalid or expired token."
|
43
|
+
render :new, status: :unprocessable_entity
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def password_params
|
50
|
+
params.require(:user).permit(:password, :password_confirmation)
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
before_action :redirect_if_authenticated, only: [:create, :new]
|
3
|
+
before_action :authenticate_user!, only: [:destroy]
|
4
|
+
|
5
|
+
def create
|
6
|
+
@user = User.authenticate_by(email: params[:user][:email].downcase, password: params[:user][:password])
|
7
|
+
if @user
|
8
|
+
if @user.unconfirmed?
|
9
|
+
redirect_to new_confirmation_path, alert: "Incorrect email or password."
|
10
|
+
else
|
11
|
+
after_login_path = session[:user_return_to] || root_path
|
12
|
+
active_session = login @user
|
13
|
+
remember(active_session) if params[:user][:remember_me] == "1"
|
14
|
+
redirect_to after_login_path, notice: "Signed in."
|
15
|
+
end
|
16
|
+
else
|
17
|
+
flash.now[:alert] = "Incorrect email or password."
|
18
|
+
render :new, status: :unprocessable_entity
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy
|
23
|
+
forget_active_session
|
24
|
+
logout
|
25
|
+
redirect_to root_path, notice: "Signed out."
|
26
|
+
end
|
27
|
+
|
28
|
+
def new
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ActiveSessionsControllerTest < ActionDispatch::IntegrationTest
|
4
|
+
setup do
|
5
|
+
@confirmed_user = User.create!(email: "confirmed_user@example.com", password: "password", password_confirmation: "password", confirmed_at: Time.current)
|
6
|
+
end
|
7
|
+
|
8
|
+
test "should destroy all active sessions" do
|
9
|
+
login @confirmed_user
|
10
|
+
@confirmed_user.active_sessions.create!
|
11
|
+
|
12
|
+
assert_difference("ActiveSession.count", -2) do
|
13
|
+
delete destroy_all_active_sessions_path
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_redirected_to root_path
|
17
|
+
assert_nil current_user
|
18
|
+
assert_not_nil flash[:notice]
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should destroy all active sessions and forget active sessions" do
|
22
|
+
login @confirmed_user, remember_user: true
|
23
|
+
@confirmed_user.active_sessions.create!
|
24
|
+
|
25
|
+
assert_difference("ActiveSession.count", -2) do
|
26
|
+
delete destroy_all_active_sessions_path
|
27
|
+
end
|
28
|
+
|
29
|
+
assert_nil current_user
|
30
|
+
assert cookies[:remember_token].blank?
|
31
|
+
end
|
32
|
+
|
33
|
+
test "should destroy another session" do
|
34
|
+
login @confirmed_user
|
35
|
+
@confirmed_user.active_sessions.create!
|
36
|
+
|
37
|
+
assert_difference("ActiveSession.count", -1) do
|
38
|
+
delete active_session_path(@confirmed_user.active_sessions.last)
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_redirected_to account_path
|
42
|
+
assert_not_nil current_user
|
43
|
+
assert_not_nil flash[:notice]
|
44
|
+
end
|
45
|
+
|
46
|
+
test "should destroy current session" do
|
47
|
+
login @confirmed_user
|
48
|
+
|
49
|
+
assert_difference("ActiveSession.count", -1) do
|
50
|
+
delete active_session_path(@confirmed_user.active_sessions.last)
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_redirected_to root_path
|
54
|
+
assert_nil current_user
|
55
|
+
assert_not_nil flash[:notice]
|
56
|
+
end
|
57
|
+
|
58
|
+
test "should destroy current session and forget current active session" do
|
59
|
+
login @confirmed_user, remember_user: true
|
60
|
+
|
61
|
+
assert_difference("ActiveSession.count", -1) do
|
62
|
+
delete active_session_path(@confirmed_user.active_sessions.last)
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_nil current_user
|
66
|
+
assert cookies[:remember_token].blank?
|
67
|
+
end
|
68
|
+
end
|