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.

Files changed (63) hide show
  1. data/CHANGELOG.md +119 -94
  2. data/Gemfile.lock +2 -2
  3. data/README.md +2 -2
  4. data/app/controllers/devise/confirmations_controller.rb +3 -8
  5. data/app/controllers/devise/passwords_controller.rb +1 -1
  6. data/app/controllers/devise/registrations_controller.rb +6 -6
  7. data/app/controllers/devise/sessions_controller.rb +3 -3
  8. data/app/controllers/devise/unlocks_controller.rb +1 -1
  9. data/app/controllers/devise_controller.rb +6 -2
  10. data/app/mailers/devise/mailer.rb +15 -13
  11. data/config/locales/en.yml +2 -3
  12. data/gemfiles/Gemfile.rails-3.2.x.lock +4 -4
  13. data/lib/devise/controllers/helpers.rb +16 -84
  14. data/lib/devise/controllers/rememberable.rb +2 -12
  15. data/lib/devise/controllers/sign_in_out.rb +103 -0
  16. data/lib/devise/failure_app.rb +11 -2
  17. data/lib/devise/hooks/forgetable.rb +1 -1
  18. data/lib/devise/hooks/proxy.rb +21 -0
  19. data/lib/devise/hooks/rememberable.rb +1 -1
  20. data/lib/devise/hooks/timeoutable.rb +4 -1
  21. data/lib/devise/models/authenticatable.rb +8 -9
  22. data/lib/devise/models/confirmable.rb +0 -4
  23. data/lib/devise/models/database_authenticatable.rb +17 -7
  24. data/lib/devise/models/lockable.rb +6 -4
  25. data/lib/devise/models/recoverable.rb +0 -8
  26. data/lib/devise/models.rb +0 -5
  27. data/lib/devise/modules.rb +0 -1
  28. data/lib/devise/parameter_sanitizer.rb +9 -3
  29. data/lib/devise/rails/routes.rb +30 -15
  30. data/lib/devise/test_helpers.rb +1 -0
  31. data/lib/devise/version.rb +1 -1
  32. data/lib/devise.rb +23 -12
  33. data/lib/generators/mongoid/devise_generator.rb +0 -3
  34. data/lib/generators/templates/devise.rb +6 -10
  35. data/lib/generators/templates/markerb/confirmation_instructions.markerb +1 -1
  36. data/lib/generators/templates/markerb/reset_password_instructions.markerb +1 -1
  37. data/lib/generators/templates/markerb/unlock_instructions.markerb +1 -1
  38. data/test/controllers/internal_helpers_test.rb +2 -2
  39. data/test/controllers/sessions_controller_test.rb +1 -1
  40. data/test/devise_test.rb +12 -1
  41. data/test/failure_app_test.rb +11 -0
  42. data/test/integration/confirmable_test.rb +11 -13
  43. data/test/integration/http_authenticatable_test.rb +0 -10
  44. data/test/integration/recoverable_test.rb +2 -2
  45. data/test/integration/rememberable_test.rb +3 -3
  46. data/test/integration/timeoutable_test.rb +28 -0
  47. data/test/mapping_test.rb +2 -2
  48. data/test/models/confirmable_test.rb +0 -9
  49. data/test/models/database_authenticatable_test.rb +19 -1
  50. data/test/models/lockable_test.rb +16 -10
  51. data/test/models/recoverable_test.rb +0 -10
  52. data/test/parameter_sanitizer_test.rb +9 -0
  53. data/test/rails_app/app/mongoid/user.rb +0 -3
  54. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +0 -3
  55. data/test/rails_app/db/schema.rb +0 -1
  56. data/test/rails_app/lib/shared_user.rb +1 -1
  57. data/test/support/locale/en.yml +4 -0
  58. data/test/test_helpers_test.rb +22 -0
  59. metadata +4 -8
  60. data/lib/devise/models/token_authenticatable.rb +0 -92
  61. data/lib/devise/strategies/token_authenticatable.rb +0 -91
  62. data/test/integration/token_authenticatable_test.rb +0 -205
  63. 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.1.0)
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.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://wiki.github.com/plataformatec/devise
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 Devise.allow_insecure_sign_in_after_confirmation
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 Devise.allow_insecure_sign_in_after_confirmation
45
- after_sign_in_path_for(resource)
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 is_navigational_format?
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 is_navigational_format?
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 is_navigational_format?
22
- expire_session_data_after_sign_in!
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 is_navigational_format?
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 is_navigational_format?
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
- expire_session_data_after_sign_in!
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 is_navigational_format?
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 && is_navigational_format?
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 is_navigational_format?
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 is_navigational_format?
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) if respond_to?(:devise_i18n_options, true)
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
- class Devise::Mailer < Devise.parent_mailer.constantize
2
- include Devise::Mailers::Helpers
1
+ if defined?(ActionMailer)
2
+ class Devise::Mailer < Devise.parent_mailer.constantize
3
+ include Devise::Mailers::Helpers
3
4
 
4
- def confirmation_instructions(record, token, opts={})
5
- @token = token
6
- devise_mail(record, :confirmation_instructions, opts)
7
- end
5
+ def confirmation_instructions(record, token, opts={})
6
+ @token = token
7
+ devise_mail(record, :confirmation_instructions, opts)
8
+ end
8
9
 
9
- def reset_password_instructions(record, token, opts={})
10
- @token = token
11
- devise_mail(record, :reset_password_instructions, opts)
12
- end
10
+ def reset_password_instructions(record, token, opts={})
11
+ @token = token
12
+ devise_mail(record, :reset_password_instructions, opts)
13
+ end
13
14
 
14
- def unlock_instructions(record, token, opts={})
15
- @token = token
16
- devise_mail(record, :unlock_instructions, opts)
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
@@ -3,16 +3,15 @@
3
3
  en:
4
4
  devise:
5
5
  confirmations:
6
- confirmed: "Your account was successfully confirmed. Please sign in."
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.1.0)
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.13)
43
- bcrypt-ruby (3.1.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.2)
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
- expire_devise_cached_variables!
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 expire_devise_cached_variables!
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
@@ -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
- I18n.t(:"#{scope}.#{message}", :resource_name => scope,
72
- :scope => "devise.failure", :default => [message])
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::Controllers::Rememberable::Proxy.new(warden).forget_me(record)
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::Controllers::Rememberable::Proxy.new(warden).remember_me(record)
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
- warden.logout(scope)
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
- # You can skip storage for http and token auth by appending values to array:
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! or downcase! when a model didn't have the
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