devise 3.1.0 → 3.2.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.
Potentially problematic release.
This version of devise might be problematic. Click here for more details.
- data/CHANGELOG.md +119 -94
- data/Gemfile.lock +2 -2
- data/README.md +2 -2
- data/app/controllers/devise/confirmations_controller.rb +3 -8
- data/app/controllers/devise/passwords_controller.rb +1 -1
- data/app/controllers/devise/registrations_controller.rb +6 -6
- data/app/controllers/devise/sessions_controller.rb +3 -3
- data/app/controllers/devise/unlocks_controller.rb +1 -1
- data/app/controllers/devise_controller.rb +6 -2
- data/app/mailers/devise/mailer.rb +15 -13
- data/config/locales/en.yml +2 -3
- data/gemfiles/Gemfile.rails-3.2.x.lock +4 -4
- data/lib/devise/controllers/helpers.rb +16 -84
- data/lib/devise/controllers/rememberable.rb +2 -12
- data/lib/devise/controllers/sign_in_out.rb +103 -0
- data/lib/devise/failure_app.rb +11 -2
- data/lib/devise/hooks/forgetable.rb +1 -1
- data/lib/devise/hooks/proxy.rb +21 -0
- data/lib/devise/hooks/rememberable.rb +1 -1
- data/lib/devise/hooks/timeoutable.rb +4 -1
- data/lib/devise/models/authenticatable.rb +8 -9
- data/lib/devise/models/confirmable.rb +0 -4
- data/lib/devise/models/database_authenticatable.rb +17 -7
- data/lib/devise/models/lockable.rb +6 -4
- data/lib/devise/models/recoverable.rb +0 -8
- data/lib/devise/models.rb +0 -5
- data/lib/devise/modules.rb +0 -1
- data/lib/devise/parameter_sanitizer.rb +9 -3
- data/lib/devise/rails/routes.rb +30 -15
- data/lib/devise/test_helpers.rb +1 -0
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +23 -12
- data/lib/generators/mongoid/devise_generator.rb +0 -3
- data/lib/generators/templates/devise.rb +6 -10
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
- data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
- data/test/controllers/internal_helpers_test.rb +2 -2
- data/test/controllers/sessions_controller_test.rb +1 -1
- data/test/devise_test.rb +12 -1
- data/test/failure_app_test.rb +11 -0
- data/test/integration/confirmable_test.rb +11 -13
- data/test/integration/http_authenticatable_test.rb +0 -10
- data/test/integration/recoverable_test.rb +2 -2
- data/test/integration/rememberable_test.rb +3 -3
- data/test/integration/timeoutable_test.rb +28 -0
- data/test/mapping_test.rb +2 -2
- data/test/models/confirmable_test.rb +0 -9
- data/test/models/database_authenticatable_test.rb +19 -1
- data/test/models/lockable_test.rb +16 -10
- data/test/models/recoverable_test.rb +0 -10
- data/test/parameter_sanitizer_test.rb +9 -0
- data/test/rails_app/app/mongoid/user.rb +0 -3
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -3
- data/test/rails_app/db/schema.rb +0 -1
- data/test/rails_app/lib/shared_user.rb +1 -1
- data/test/support/locale/en.yml +4 -0
- data/test/test_helpers_test.rb +22 -0
- metadata +4 -8
- data/lib/devise/models/token_authenticatable.rb +0 -92
- data/lib/devise/strategies/token_authenticatable.rb +0 -91
- data/test/integration/token_authenticatable_test.rb +0 -205
- data/test/models/token_authenticatable_test.rb +0 -55
data/Gemfile.lock
CHANGED
@@ -12,7 +12,7 @@ GIT
|
|
12
12
|
PATH
|
13
13
|
remote: .
|
14
14
|
specs:
|
15
|
-
devise (3.
|
15
|
+
devise (3.2.0)
|
16
16
|
bcrypt-ruby (~> 3.0)
|
17
17
|
orm_adapter (~> 0.1)
|
18
18
|
railties (>= 3.2.6, < 5)
|
@@ -48,7 +48,7 @@ GEM
|
|
48
48
|
tzinfo (~> 0.3.37)
|
49
49
|
arel (4.0.0)
|
50
50
|
atomic (1.1.12)
|
51
|
-
bcrypt-ruby (3.1.
|
51
|
+
bcrypt-ruby (3.1.2)
|
52
52
|
builder (3.1.4)
|
53
53
|
erubis (2.7.0)
|
54
54
|
faraday (0.8.8)
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ Devise is guaranteed to be thread-safe on YARV. Thread-safety support on JRuby i
|
|
35
35
|
|
36
36
|
The Devise Wiki has lots of additional information about Devise including many "how-to" articles and answers to the most frequently asked questions. Please browse the Wiki after finishing this README:
|
37
37
|
|
38
|
-
https://
|
38
|
+
https://github.com/plataformatec/devise/wiki
|
39
39
|
|
40
40
|
### Bug reports
|
41
41
|
|
@@ -445,7 +445,7 @@ https://github.com/hassox/warden
|
|
445
445
|
|
446
446
|
We have a long list of valued contributors. Check them all at:
|
447
447
|
|
448
|
-
https://github.com/plataformatec/devise/contributors
|
448
|
+
https://github.com/plataformatec/devise/graphs/contributors
|
449
449
|
|
450
450
|
## License
|
451
451
|
|
@@ -20,12 +20,7 @@ class Devise::ConfirmationsController < DeviseController
|
|
20
20
|
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
21
21
|
|
22
22
|
if resource.errors.empty?
|
23
|
-
if
|
24
|
-
set_flash_message(:notice, :confirmed_and_signed_in) if is_navigational_format?
|
25
|
-
sign_in(resource_name, resource)
|
26
|
-
else
|
27
|
-
set_flash_message(:notice, :confirmed) if is_navigational_format?
|
28
|
-
end
|
23
|
+
set_flash_message(:notice, :confirmed) if is_flashing_format?
|
29
24
|
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
|
30
25
|
else
|
31
26
|
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
@@ -41,8 +36,8 @@ class Devise::ConfirmationsController < DeviseController
|
|
41
36
|
|
42
37
|
# The path used after confirmation.
|
43
38
|
def after_confirmation_path_for(resource_name, resource)
|
44
|
-
if
|
45
|
-
|
39
|
+
if signed_in?
|
40
|
+
signed_in_root_path(resource)
|
46
41
|
else
|
47
42
|
new_session_path(resource_name)
|
48
43
|
end
|
@@ -32,7 +32,7 @@ class Devise::PasswordsController < DeviseController
|
|
32
32
|
if resource.errors.empty?
|
33
33
|
resource.unlock_access! if unlockable?(resource)
|
34
34
|
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
|
35
|
-
set_flash_message(:notice, flash_message) if
|
35
|
+
set_flash_message(:notice, flash_message) if is_flashing_format?
|
36
36
|
sign_in(resource_name, resource)
|
37
37
|
respond_with resource, :location => after_resetting_password_path_for(resource)
|
38
38
|
else
|
@@ -14,12 +14,12 @@ class Devise::RegistrationsController < DeviseController
|
|
14
14
|
|
15
15
|
if resource.save
|
16
16
|
if resource.active_for_authentication?
|
17
|
-
set_flash_message :notice, :signed_up if
|
17
|
+
set_flash_message :notice, :signed_up if is_flashing_format?
|
18
18
|
sign_up(resource_name, resource)
|
19
19
|
respond_with resource, :location => after_sign_up_path_for(resource)
|
20
20
|
else
|
21
|
-
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if
|
22
|
-
|
21
|
+
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
|
22
|
+
expire_data_after_sign_in!
|
23
23
|
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
|
24
24
|
end
|
25
25
|
else
|
@@ -41,7 +41,7 @@ class Devise::RegistrationsController < DeviseController
|
|
41
41
|
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
|
42
42
|
|
43
43
|
if update_resource(resource, account_update_params)
|
44
|
-
if
|
44
|
+
if is_flashing_format?
|
45
45
|
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
|
46
46
|
:update_needs_confirmation : :updated
|
47
47
|
set_flash_message :notice, flash_key
|
@@ -58,7 +58,7 @@ class Devise::RegistrationsController < DeviseController
|
|
58
58
|
def destroy
|
59
59
|
resource.destroy
|
60
60
|
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
61
|
-
set_flash_message :notice, :destroyed if
|
61
|
+
set_flash_message :notice, :destroyed if is_flashing_format?
|
62
62
|
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
|
63
63
|
end
|
64
64
|
|
@@ -68,7 +68,7 @@ class Devise::RegistrationsController < DeviseController
|
|
68
68
|
# cancel oauth signing in/up in the middle of the process,
|
69
69
|
# removing all OAuth session data.
|
70
70
|
def cancel
|
71
|
-
|
71
|
+
expire_data_after_sign_in!
|
72
72
|
redirect_to new_registration_path(resource_name)
|
73
73
|
end
|
74
74
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Devise::SessionsController < DeviseController
|
2
2
|
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
|
3
3
|
prepend_before_filter :allow_params_authentication!, :only => :create
|
4
|
-
prepend_before_filter { request.env["devise.skip_timeout"] = true }
|
4
|
+
prepend_before_filter :only => [ :create, :destroy ] { request.env["devise.skip_timeout"] = true }
|
5
5
|
|
6
6
|
# GET /resource/sign_in
|
7
7
|
def new
|
@@ -13,7 +13,7 @@ class Devise::SessionsController < DeviseController
|
|
13
13
|
# POST /resource/sign_in
|
14
14
|
def create
|
15
15
|
self.resource = warden.authenticate!(auth_options)
|
16
|
-
set_flash_message(:notice, :signed_in) if
|
16
|
+
set_flash_message(:notice, :signed_in) if is_flashing_format?
|
17
17
|
sign_in(resource_name, resource)
|
18
18
|
respond_with resource, :location => after_sign_in_path_for(resource)
|
19
19
|
end
|
@@ -22,7 +22,7 @@ class Devise::SessionsController < DeviseController
|
|
22
22
|
def destroy
|
23
23
|
redirect_path = after_sign_out_path_for(resource_name)
|
24
24
|
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
|
25
|
-
set_flash_message :notice, :signed_out if signed_out &&
|
25
|
+
set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
|
26
26
|
|
27
27
|
# We actually need to hardcode this as Rails default responder doesn't
|
28
28
|
# support returning empty response on GET request
|
@@ -22,7 +22,7 @@ class Devise::UnlocksController < DeviseController
|
|
22
22
|
self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
|
23
23
|
|
24
24
|
if resource.errors.empty?
|
25
|
-
set_flash_message :notice, :unlocked if
|
25
|
+
set_flash_message :notice, :unlocked if is_flashing_format?
|
26
26
|
respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
|
27
27
|
else
|
28
28
|
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
@@ -123,7 +123,7 @@ MESSAGE
|
|
123
123
|
end
|
124
124
|
|
125
125
|
if notice
|
126
|
-
set_flash_message :notice, notice if
|
126
|
+
set_flash_message :notice, notice if is_flashing_format?
|
127
127
|
true
|
128
128
|
end
|
129
129
|
end
|
@@ -147,12 +147,16 @@ MESSAGE
|
|
147
147
|
flash[key] = message if message.present?
|
148
148
|
end
|
149
149
|
|
150
|
+
def devise_i18n_options(options)
|
151
|
+
options
|
152
|
+
end
|
153
|
+
|
150
154
|
# Get message for given
|
151
155
|
def find_message(kind, options = {})
|
152
156
|
options[:scope] = "devise.#{controller_name}"
|
153
157
|
options[:default] = Array(options[:default]).unshift(kind.to_sym)
|
154
158
|
options[:resource_name] = resource_name
|
155
|
-
options = devise_i18n_options(options)
|
159
|
+
options = devise_i18n_options(options)
|
156
160
|
I18n.t("#{options[:resource_name]}.#{kind}", options)
|
157
161
|
end
|
158
162
|
|
@@ -1,18 +1,20 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
if defined?(ActionMailer)
|
2
|
+
class Devise::Mailer < Devise.parent_mailer.constantize
|
3
|
+
include Devise::Mailers::Helpers
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
def confirmation_instructions(record, token, opts={})
|
6
|
+
@token = token
|
7
|
+
devise_mail(record, :confirmation_instructions, opts)
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def reset_password_instructions(record, token, opts={})
|
11
|
+
@token = token
|
12
|
+
devise_mail(record, :reset_password_instructions, opts)
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def unlock_instructions(record, token, opts={})
|
16
|
+
@token = token
|
17
|
+
devise_mail(record, :unlock_instructions, opts)
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
data/config/locales/en.yml
CHANGED
@@ -3,16 +3,15 @@
|
|
3
3
|
en:
|
4
4
|
devise:
|
5
5
|
confirmations:
|
6
|
-
confirmed: "Your account was successfully confirmed.
|
7
|
-
confirmed_and_signed_in: "Your account was successfully confirmed. You are now signed in."
|
6
|
+
confirmed: "Your account was successfully confirmed."
|
8
7
|
send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
|
9
8
|
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
|
10
9
|
failure:
|
11
10
|
already_authenticated: "You are already signed in."
|
12
11
|
inactive: "Your account is not activated yet."
|
13
12
|
invalid: "Invalid email or password."
|
14
|
-
invalid_token: "Invalid authentication token."
|
15
13
|
locked: "Your account is locked."
|
14
|
+
last_attempt: "You have one more attempt before your account will be locked."
|
16
15
|
not_found_in_database: "Invalid email or password."
|
17
16
|
timeout: "Your session expired. Please sign in again to continue."
|
18
17
|
unauthenticated: "You need to sign in or sign up before continuing."
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
devise (3.
|
4
|
+
devise (3.2.0)
|
5
5
|
bcrypt-ruby (~> 3.0)
|
6
6
|
orm_adapter (~> 0.1)
|
7
7
|
railties (>= 3.2.6, < 5)
|
@@ -39,8 +39,8 @@ GEM
|
|
39
39
|
i18n (~> 0.6, >= 0.6.4)
|
40
40
|
multi_json (~> 1.0)
|
41
41
|
arel (3.0.2)
|
42
|
-
atomic (1.1.
|
43
|
-
bcrypt-ruby (3.1.
|
42
|
+
atomic (1.1.14)
|
43
|
+
bcrypt-ruby (3.1.2)
|
44
44
|
builder (3.0.4)
|
45
45
|
erubis (2.7.0)
|
46
46
|
faraday (0.8.8)
|
@@ -125,7 +125,7 @@ GEM
|
|
125
125
|
tilt (~> 1.1, != 1.3.0)
|
126
126
|
sqlite3 (1.3.7)
|
127
127
|
thor (0.18.1)
|
128
|
-
thread_safe (0.1.
|
128
|
+
thread_safe (0.1.3)
|
129
129
|
atomic
|
130
130
|
tilt (1.4.1)
|
131
131
|
treetop (1.4.14)
|
@@ -3,6 +3,7 @@ module Devise
|
|
3
3
|
# Those helpers are convenience methods added to ApplicationController.
|
4
4
|
module Helpers
|
5
5
|
extend ActiveSupport::Concern
|
6
|
+
include Devise::Controllers::SignInOut
|
6
7
|
|
7
8
|
included do
|
8
9
|
helper_method :warden, :signed_in?, :devise_controller?
|
@@ -96,84 +97,6 @@ module Devise
|
|
96
97
|
request.env["devise.allow_params_authentication"] = true
|
97
98
|
end
|
98
99
|
|
99
|
-
# Return true if the given scope is signed in session. If no scope given, return
|
100
|
-
# true if any scope is signed in. Does not run authentication hooks.
|
101
|
-
def signed_in?(scope=nil)
|
102
|
-
[ scope || Devise.mappings.keys ].flatten.any? do |_scope|
|
103
|
-
warden.authenticate?(:scope => _scope)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Sign in a user that already was authenticated. This helper is useful for logging
|
108
|
-
# users in after sign up.
|
109
|
-
#
|
110
|
-
# All options given to sign_in is passed forward to the set_user method in warden.
|
111
|
-
# The only exception is the :bypass option, which bypass warden callbacks and stores
|
112
|
-
# the user straight in session. This option is useful in cases the user is already
|
113
|
-
# signed in, but we want to refresh the credentials in session.
|
114
|
-
#
|
115
|
-
# Examples:
|
116
|
-
#
|
117
|
-
# sign_in :user, @user # sign_in(scope, resource)
|
118
|
-
# sign_in @user # sign_in(resource)
|
119
|
-
# sign_in @user, :event => :authentication # sign_in(resource, options)
|
120
|
-
# sign_in @user, :store => false # sign_in(resource, options)
|
121
|
-
# sign_in @user, :bypass => true # sign_in(resource, options)
|
122
|
-
#
|
123
|
-
def sign_in(resource_or_scope, *args)
|
124
|
-
options = args.extract_options!
|
125
|
-
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
126
|
-
resource = args.last || resource_or_scope
|
127
|
-
|
128
|
-
expire_session_data_after_sign_in!
|
129
|
-
|
130
|
-
if options[:bypass]
|
131
|
-
warden.session_serializer.store(resource, scope)
|
132
|
-
elsif warden.user(scope) == resource && !options.delete(:force)
|
133
|
-
# Do nothing. User already signed in and we are not forcing it.
|
134
|
-
true
|
135
|
-
else
|
136
|
-
warden.set_user(resource, options.merge!(:scope => scope))
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Sign out a given user or scope. This helper is useful for signing out a user
|
141
|
-
# after deleting accounts. Returns true if there was a logout and false if there
|
142
|
-
# is no user logged in on the referred scope
|
143
|
-
#
|
144
|
-
# Examples:
|
145
|
-
#
|
146
|
-
# sign_out :user # sign_out(scope)
|
147
|
-
# sign_out @user # sign_out(resource)
|
148
|
-
#
|
149
|
-
def sign_out(resource_or_scope=nil)
|
150
|
-
return sign_out_all_scopes unless resource_or_scope
|
151
|
-
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
152
|
-
user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
|
153
|
-
|
154
|
-
warden.raw_session.inspect # Without this inspect here. The session does not clear.
|
155
|
-
warden.logout(scope)
|
156
|
-
warden.clear_strategies_cache!(:scope => scope)
|
157
|
-
instance_variable_set(:"@current_#{scope}", nil)
|
158
|
-
|
159
|
-
!!user
|
160
|
-
end
|
161
|
-
|
162
|
-
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
163
|
-
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
|
164
|
-
# and false if there was no user logged in on all scopes.
|
165
|
-
def sign_out_all_scopes(lock=true)
|
166
|
-
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
|
167
|
-
|
168
|
-
warden.raw_session.inspect
|
169
|
-
warden.logout
|
170
|
-
expire_devise_cached_variables!
|
171
|
-
warden.clear_strategies_cache!
|
172
|
-
warden.lock! if lock
|
173
|
-
|
174
|
-
users.any?
|
175
|
-
end
|
176
|
-
|
177
100
|
# Returns and delete (if it's navigational format) the url stored in the session for
|
178
101
|
# the given scope. Useful for giving redirect backs after sign up:
|
179
102
|
#
|
@@ -257,10 +180,6 @@ module Devise
|
|
257
180
|
redirect_to after_sign_in_path_for(resource)
|
258
181
|
end
|
259
182
|
|
260
|
-
def expire_session_data_after_sign_in!
|
261
|
-
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
262
|
-
end
|
263
|
-
|
264
183
|
# Sign out a user and tries to redirect to the url specified by
|
265
184
|
# after_sign_out_path_for.
|
266
185
|
def sign_out_and_redirect(resource_or_scope)
|
@@ -275,7 +194,7 @@ module Devise
|
|
275
194
|
def handle_unverified_request
|
276
195
|
sign_out_all_scopes(false)
|
277
196
|
request.env["devise.skip_storage"] = true
|
278
|
-
|
197
|
+
expire_data_after_sign_out!
|
279
198
|
super # call the default behaviour which resets the session
|
280
199
|
end
|
281
200
|
|
@@ -287,10 +206,23 @@ module Devise
|
|
287
206
|
Devise.navigational_formats.include?(request_format)
|
288
207
|
end
|
289
208
|
|
209
|
+
# Check if flash messages should be emitted. Default is to do it on
|
210
|
+
# navigational formats
|
211
|
+
def is_flashing_format?
|
212
|
+
is_navigational_format?
|
213
|
+
end
|
214
|
+
|
290
215
|
private
|
291
216
|
|
292
|
-
def
|
217
|
+
def expire_session_data_after_sign_in!
|
218
|
+
ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated " \
|
219
|
+
"in favor of expire_data_after_sign_in!"
|
220
|
+
expire_data_after_sign_in!
|
221
|
+
end
|
222
|
+
|
223
|
+
def expire_data_after_sign_out!
|
293
224
|
Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
|
225
|
+
super
|
294
226
|
end
|
295
227
|
end
|
296
228
|
end
|
@@ -1,24 +1,14 @@
|
|
1
1
|
module Devise
|
2
2
|
module Controllers
|
3
3
|
# A module that may be optionally included in a controller in order
|
4
|
-
# to provide remember me behavior.
|
4
|
+
# to provide remember me behavior. Useful when signing in is done
|
5
|
+
# through a callback, like in Omniauth.
|
5
6
|
module Rememberable
|
6
7
|
# Return default cookie values retrieved from session options.
|
7
8
|
def self.cookie_values
|
8
9
|
Rails.configuration.session_options.slice(:path, :domain, :secure)
|
9
10
|
end
|
10
11
|
|
11
|
-
# A small warden proxy so we can remember and forget uses from hooks.
|
12
|
-
class Proxy #:nodoc:
|
13
|
-
include Devise::Controllers::Rememberable
|
14
|
-
|
15
|
-
delegate :cookies, :env, :to => :@warden
|
16
|
-
|
17
|
-
def initialize(warden)
|
18
|
-
@warden = warden
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
12
|
# Remembers the given resource by setting up a cookie
|
23
13
|
def remember_me(resource)
|
24
14
|
return if env["devise.skip_storage"]
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Devise
|
2
|
+
module Controllers
|
3
|
+
# Provide sign in and sign out functionality.
|
4
|
+
# Included by default in all controllers.
|
5
|
+
module SignInOut
|
6
|
+
# Return true if the given scope is signed in session. If no scope given, return
|
7
|
+
# true if any scope is signed in. Does not run authentication hooks.
|
8
|
+
def signed_in?(scope=nil)
|
9
|
+
[ scope || Devise.mappings.keys ].flatten.any? do |_scope|
|
10
|
+
warden.authenticate?(:scope => _scope)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sign in a user that already was authenticated. This helper is useful for logging
|
15
|
+
# users in after sign up.
|
16
|
+
#
|
17
|
+
# All options given to sign_in is passed forward to the set_user method in warden.
|
18
|
+
# The only exception is the :bypass option, which bypass warden callbacks and stores
|
19
|
+
# the user straight in session. This option is useful in cases the user is already
|
20
|
+
# signed in, but we want to refresh the credentials in session.
|
21
|
+
#
|
22
|
+
# Examples:
|
23
|
+
#
|
24
|
+
# sign_in :user, @user # sign_in(scope, resource)
|
25
|
+
# sign_in @user # sign_in(resource)
|
26
|
+
# sign_in @user, :event => :authentication # sign_in(resource, options)
|
27
|
+
# sign_in @user, :store => false # sign_in(resource, options)
|
28
|
+
# sign_in @user, :bypass => true # sign_in(resource, options)
|
29
|
+
#
|
30
|
+
def sign_in(resource_or_scope, *args)
|
31
|
+
options = args.extract_options!
|
32
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
33
|
+
resource = args.last || resource_or_scope
|
34
|
+
|
35
|
+
expire_data_after_sign_in!
|
36
|
+
|
37
|
+
if options[:bypass]
|
38
|
+
warden.session_serializer.store(resource, scope)
|
39
|
+
elsif warden.user(scope) == resource && !options.delete(:force)
|
40
|
+
# Do nothing. User already signed in and we are not forcing it.
|
41
|
+
true
|
42
|
+
else
|
43
|
+
warden.set_user(resource, options.merge!(:scope => scope))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Sign out a given user or scope. This helper is useful for signing out a user
|
48
|
+
# after deleting accounts. Returns true if there was a logout and false if there
|
49
|
+
# is no user logged in on the referred scope
|
50
|
+
#
|
51
|
+
# Examples:
|
52
|
+
#
|
53
|
+
# sign_out :user # sign_out(scope)
|
54
|
+
# sign_out @user # sign_out(resource)
|
55
|
+
#
|
56
|
+
def sign_out(resource_or_scope=nil)
|
57
|
+
return sign_out_all_scopes unless resource_or_scope
|
58
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
59
|
+
user = warden.user(:scope => scope, :run_callbacks => false) # If there is no user
|
60
|
+
|
61
|
+
warden.raw_session.inspect # Without this inspect here. The session does not clear.
|
62
|
+
warden.logout(scope)
|
63
|
+
warden.clear_strategies_cache!(:scope => scope)
|
64
|
+
instance_variable_set(:"@current_#{scope}", nil)
|
65
|
+
|
66
|
+
!!user
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
70
|
+
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
|
71
|
+
# and false if there was no user logged in on all scopes.
|
72
|
+
def sign_out_all_scopes(lock=true)
|
73
|
+
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
|
74
|
+
|
75
|
+
warden.raw_session.inspect
|
76
|
+
warden.logout
|
77
|
+
expire_data_after_sign_out!
|
78
|
+
warden.clear_strategies_cache!
|
79
|
+
warden.lock! if lock
|
80
|
+
|
81
|
+
users.any?
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def expire_data_after_sign_in!
|
87
|
+
# session.keys will return an empty array if the session is not yet loaded.
|
88
|
+
# This is a bug in both Rack and Rails.
|
89
|
+
# A call to #empty? forces the session to be loaded.
|
90
|
+
session.empty?
|
91
|
+
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def expire_data_after_sign_out!
|
95
|
+
# session.keys will return an empty array if the session is not yet loaded.
|
96
|
+
# This is a bug in both Rack and Rails.
|
97
|
+
# A call to #empty? forces the session to be loaded.
|
98
|
+
session.empty?
|
99
|
+
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/devise/failure_app.rb
CHANGED
@@ -64,12 +64,21 @@ module Devise
|
|
64
64
|
|
65
65
|
protected
|
66
66
|
|
67
|
+
def i18n_options(options)
|
68
|
+
options
|
69
|
+
end
|
70
|
+
|
67
71
|
def i18n_message(default = nil)
|
68
72
|
message = warden_message || default || :unauthenticated
|
69
73
|
|
70
74
|
if message.is_a?(Symbol)
|
71
|
-
|
72
|
-
|
75
|
+
options = {}
|
76
|
+
options[:resource_name] = scope
|
77
|
+
options[:scope] = "devise.failure"
|
78
|
+
options[:default] = [message]
|
79
|
+
options = i18n_options(options)
|
80
|
+
|
81
|
+
I18n.t(:"#{scope}.#{message}", options)
|
73
82
|
else
|
74
83
|
message.to_s
|
75
84
|
end
|
@@ -4,6 +4,6 @@
|
|
4
4
|
# This avoids forgetting deleted users.
|
5
5
|
Warden::Manager.before_logout do |record, warden, options|
|
6
6
|
if record.respond_to?(:forget_me!)
|
7
|
-
Devise::
|
7
|
+
Devise::Hooks::Proxy.new(warden).forget_me(record)
|
8
8
|
end
|
9
9
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Devise
|
2
|
+
module Hooks
|
3
|
+
# A small warden proxy so we can remember, forget and
|
4
|
+
# sign out users from hooks.
|
5
|
+
class Proxy #:nodoc:
|
6
|
+
include Devise::Controllers::Rememberable
|
7
|
+
include Devise::Controllers::SignInOut
|
8
|
+
|
9
|
+
attr_reader :warden
|
10
|
+
delegate :cookies, :env, :to => :warden
|
11
|
+
|
12
|
+
def initialize(warden)
|
13
|
+
@warden = warden
|
14
|
+
end
|
15
|
+
|
16
|
+
def session
|
17
|
+
warden.request.session
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,6 +2,6 @@ Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
|
2
2
|
scope = options[:scope]
|
3
3
|
if record.respond_to?(:remember_me) && options[:store] != false &&
|
4
4
|
record.remember_me && warden.authenticated?(scope)
|
5
|
-
Devise::
|
5
|
+
Devise::Hooks::Proxy.new(warden).remember_me(record)
|
6
6
|
end
|
7
7
|
end
|
@@ -9,12 +9,15 @@ Warden::Manager.after_set_user do |record, warden, options|
|
|
9
9
|
|
10
10
|
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
|
11
11
|
last_request_at = warden.session(scope)['last_request_at']
|
12
|
+
proxy = Devise::Hooks::Proxy.new(warden)
|
12
13
|
|
13
14
|
if record.timedout?(last_request_at) && !env['devise.skip_timeout']
|
14
|
-
|
15
|
+
Devise.sign_out_all_scopes ? proxy.sign_out : sign_out(scope)
|
16
|
+
|
15
17
|
if record.respond_to?(:expire_auth_token_on_timeout) && record.expire_auth_token_on_timeout
|
16
18
|
record.reset_authentication_token!
|
17
19
|
end
|
20
|
+
|
18
21
|
throw :warden, :scope => scope, :message => :timeout
|
19
22
|
end
|
20
23
|
|
@@ -29,9 +29,7 @@ module Devise
|
|
29
29
|
# It also accepts an array specifying the strategies that should allow params authentication.
|
30
30
|
#
|
31
31
|
# * +skip_session_storage+: By default Devise will store the user in session.
|
32
|
-
#
|
33
|
-
# :skip_session_storage => [:token_auth] or :skip_session_storage => [:http_auth, :token_auth],
|
34
|
-
# by default is set to :skip_session_storage => [:http_auth].
|
32
|
+
# By default is set to :skip_session_storage => [:http_auth].
|
35
33
|
#
|
36
34
|
# == active_for_authentication?
|
37
35
|
#
|
@@ -176,23 +174,24 @@ module Devise
|
|
176
174
|
end
|
177
175
|
|
178
176
|
def downcase_keys
|
179
|
-
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase
|
177
|
+
self.class.case_insensitive_keys.each { |k| apply_to_attribute_or_variable(k, :downcase) }
|
180
178
|
end
|
181
179
|
|
182
180
|
def strip_whitespace
|
183
|
-
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip
|
181
|
+
self.class.strip_whitespace_keys.each { |k| apply_to_attribute_or_variable(k, :strip) }
|
184
182
|
end
|
185
183
|
|
186
184
|
def apply_to_attribute_or_variable(attr, method)
|
187
185
|
if self[attr]
|
188
|
-
self[attr].try(method)
|
186
|
+
self[attr] = self[attr].try(method)
|
189
187
|
|
190
188
|
# Use respond_to? here to avoid a regression where globally
|
191
189
|
# configured strip_whitespace_keys or case_insensitive_keys were
|
192
|
-
# attempting to strip
|
190
|
+
# attempting to strip or downcase when a model didn't have the
|
193
191
|
# globally configured key.
|
194
|
-
elsif respond_to?(attr)
|
195
|
-
send(attr).try(method)
|
192
|
+
elsif respond_to?(attr) && respond_to?("#{attr}=")
|
193
|
+
new_value = send(attr).try(method)
|
194
|
+
send("#{attr}=", new_value)
|
196
195
|
end
|
197
196
|
end
|
198
197
|
|
@@ -275,10 +275,6 @@ module Devise
|
|
275
275
|
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
|
276
276
|
|
277
277
|
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
|
278
|
-
if !confirmable.persisted? && Devise.allow_insecure_token_lookup
|
279
|
-
confirmable = find_or_initialize_with_error_by(:confirmation_token, original_token)
|
280
|
-
end
|
281
|
-
|
282
278
|
confirmable.confirm! if confirmable.persisted?
|
283
279
|
confirmable.confirmation_token = original_token
|
284
280
|
confirmable
|