devise 2.2.3 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (66) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +0 -7
  3. data/.yardopts +9 -0
  4. data/CHANGELOG.rdoc +18 -0
  5. data/Gemfile +4 -4
  6. data/Gemfile.lock +57 -57
  7. data/README.md +8 -4
  8. data/Rakefile +1 -0
  9. data/app/controllers/devise/confirmations_controller.rb +1 -1
  10. data/app/controllers/devise/passwords_controller.rb +5 -2
  11. data/app/controllers/devise/sessions_controller.rb +0 -1
  12. data/app/controllers/devise/unlocks_controller.rb +2 -2
  13. data/app/controllers/devise_controller.rb +9 -4
  14. data/app/views/devise/registrations/edit.html.erb +1 -1
  15. data/devise.gemspec +1 -0
  16. data/devise.png +0 -0
  17. data/gemfiles/Gemfile.rails-3.1.x +4 -4
  18. data/gemfiles/Gemfile.rails-3.1.x.lock +56 -56
  19. data/lib/devise.rb +18 -2
  20. data/lib/devise/mailers/helpers.rb +5 -4
  21. data/lib/devise/models/authenticatable.rb +24 -8
  22. data/lib/devise/models/confirmable.rb +23 -3
  23. data/lib/devise/models/database_authenticatable.rb +15 -0
  24. data/lib/devise/models/omniauthable.rb +2 -2
  25. data/lib/devise/models/recoverable.rb +1 -1
  26. data/lib/devise/models/timeoutable.rb +1 -1
  27. data/lib/devise/param_filter.rb +8 -8
  28. data/lib/devise/rails/routes.rb +22 -17
  29. data/lib/devise/rails/warden_compat.rb +0 -29
  30. data/lib/devise/strategies/authenticatable.rb +8 -5
  31. data/lib/devise/strategies/token_authenticatable.rb +38 -3
  32. data/lib/devise/version.rb +1 -1
  33. data/lib/generators/devise/views_generator.rb +8 -2
  34. data/lib/generators/templates/devise.rb +10 -4
  35. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +1 -1
  36. data/test/controllers/passwords_controller_test.rb +32 -0
  37. data/test/failure_app_test.rb +3 -3
  38. data/test/generators/views_generator_test.rb +16 -1
  39. data/test/helpers/devise_helper_test.rb +1 -1
  40. data/test/integration/authenticatable_test.rb +72 -25
  41. data/test/integration/confirmable_test.rb +6 -6
  42. data/test/integration/database_authenticatable_test.rb +1 -1
  43. data/test/integration/http_authenticatable_test.rb +19 -1
  44. data/test/integration/lockable_test.rb +1 -1
  45. data/test/integration/omniauthable_test.rb +2 -2
  46. data/test/integration/recoverable_test.rb +2 -2
  47. data/test/integration/registerable_test.rb +4 -4
  48. data/test/integration/rememberable_test.rb +9 -9
  49. data/test/integration/timeoutable_test.rb +1 -1
  50. data/test/integration/token_authenticatable_test.rb +45 -1
  51. data/test/integration/trackable_test.rb +1 -1
  52. data/test/mailers/confirmation_instructions_test.rb +11 -2
  53. data/test/mailers/reset_password_instructions_test.rb +11 -2
  54. data/test/mailers/unlock_instructions_test.rb +11 -1
  55. data/test/models/authenticatable_test.rb +3 -3
  56. data/test/models/confirmable_test.rb +17 -0
  57. data/test/models/database_authenticatable_test.rb +32 -0
  58. data/test/models/lockable_test.rb +1 -1
  59. data/test/models/rememberable_test.rb +4 -3
  60. data/test/models/serializable_test.rb +6 -6
  61. data/test/models/validatable_test.rb +3 -3
  62. data/test/models_test.rb +6 -1
  63. data/test/rails_app/app/mailers/users/mailer.rb +5 -1
  64. data/test/rails_app/config/routes.rb +13 -13
  65. data/test/test_helper.rb +1 -1
  66. metadata +23 -28
@@ -1,7 +1,7 @@
1
1
  module Devise
2
2
  module Models
3
3
 
4
- # Recoverable takes care of reseting the user password and send reset instructions.
4
+ # Recoverable takes care of resetting the user password and send reset instructions.
5
5
  #
6
6
  # ==Options
7
7
  #
@@ -2,7 +2,7 @@ require 'devise/hooks/timeoutable'
2
2
 
3
3
  module Devise
4
4
  module Models
5
- # Timeoutable takes care of veryfing whether a user session has already
5
+ # Timeoutable takes care of verifyng whether a user session has already
6
6
  # expired or not. When a session expires after the configured time, the user
7
7
  # will be asked for credentials again, it means, he/she will be redirected
8
8
  # to the sign in page.
@@ -8,16 +8,16 @@ module Devise
8
8
  def filter(conditions)
9
9
  conditions = stringify_params(conditions.dup)
10
10
 
11
- @case_insensitive_keys.each do |k|
12
- value = conditions[k]
13
- next unless value.respond_to?(:downcase)
14
- conditions[k] = value.downcase
15
- end
11
+ conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :downcase, @case_insensitive_keys))
12
+ conditions.merge!(filtered_hash_by_method_for_given_keys(conditions.dup, :strip, @strip_whitespace_keys))
13
+
14
+ conditions
15
+ end
16
16
 
17
- @strip_whitespace_keys.each do |k|
17
+ def filtered_hash_by_method_for_given_keys(conditions, method, condition_keys)
18
+ condition_keys.each do |k|
18
19
  value = conditions[k]
19
- next unless value.respond_to?(:strip)
20
- conditions[k] = value.strip
20
+ conditions[k] = value.send(method) if value.respond_to?(method)
21
21
  end
22
22
 
23
23
  conditions
@@ -250,15 +250,11 @@ module ActionDispatch::Routing
250
250
  # end
251
251
  #
252
252
  # authenticate :user, lambda {|u| u.role == "admin"} do
253
- # root :to => "admin/dashboard#show"
253
+ # root :to => "admin/dashboard#show", :as => :user_root
254
254
  # end
255
255
  #
256
256
  def authenticate(scope=nil, block=nil)
257
- constraint = lambda do |request|
258
- request.env["warden"].authenticate!(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
259
- end
260
-
261
- constraints(constraint) do
257
+ constraints_for(:authenticate!, scope, block) do
262
258
  yield
263
259
  end
264
260
  end
@@ -268,25 +264,21 @@ module ActionDispatch::Routing
268
264
  # a model and allows extra constraints to be done on the instance.
269
265
  #
270
266
  # authenticated :admin do
271
- # root :to => 'admin/dashboard#show'
267
+ # root :to => 'admin/dashboard#show', :as => :admin_root
272
268
  # end
273
269
  #
274
270
  # authenticated do
275
- # root :to => 'dashboard#show'
271
+ # root :to => 'dashboard#show', :as => :authenticated_root
276
272
  # end
277
273
  #
278
274
  # authenticated :user, lambda {|u| u.role == "admin"} do
279
- # root :to => "admin/dashboard#show"
275
+ # root :to => "admin/dashboard#show", :as => :user_root
280
276
  # end
281
277
  #
282
278
  # root :to => 'landing#show'
283
279
  #
284
280
  def authenticated(scope=nil, block=nil)
285
- constraint = lambda do |request|
286
- request.env["warden"].authenticate?(:scope => scope) && (block.nil? || block.call(request.env["warden"].user(scope)))
287
- end
288
-
289
- constraints(constraint) do
281
+ constraints_for(:authenticate?, scope, block) do
290
282
  yield
291
283
  end
292
284
  end
@@ -329,7 +321,7 @@ module ActionDispatch::Routing
329
321
  # good and working example.
330
322
  #
331
323
  # devise_scope :user do
332
- # match "/some/route" => "some_devise_controller"
324
+ # get "/some/route" => "some_devise_controller"
333
325
  # end
334
326
  # devise_for :users
335
327
  #
@@ -401,12 +393,14 @@ module ActionDispatch::Routing
401
393
  match "#{path_prefix}/:provider",
402
394
  :constraints => { :provider => providers },
403
395
  :to => "#{controllers[:omniauth_callbacks]}#passthru",
404
- :as => :omniauth_authorize
396
+ :as => :omniauth_authorize,
397
+ :via => [:get, :post]
405
398
 
406
399
  match "#{path_prefix}/:action/callback",
407
400
  :constraints => { :action => providers },
408
401
  :to => controllers[:omniauth_callbacks],
409
- :as => :omniauth_callback
402
+ :as => :omniauth_callback,
403
+ :via => [:get, :post]
410
404
  ensure
411
405
  @scope[:path] = path
412
406
  end
@@ -426,6 +420,17 @@ module ActionDispatch::Routing
426
420
  @scope.merge!(old)
427
421
  end
428
422
 
423
+ def constraints_for(method_to_apply, scope=nil, block=nil)
424
+ constraint = lambda do |request|
425
+ request.env['warden'].send(method_to_apply, :scope => scope) &&
426
+ (block.nil? || block.call(request.env["warden"].user(scope)))
427
+ end
428
+
429
+ constraints(constraint) do
430
+ yield
431
+ end
432
+ end
433
+
429
434
  def set_omniauth_path_prefix!(path_prefix) #:nodoc:
430
435
  if ::OmniAuth.config.path_prefix && ::OmniAuth.config.path_prefix != path_prefix
431
436
  raise "Wrong OmniAuth configuration. If you are getting this exception, it means that either:\n\n" \
@@ -12,32 +12,3 @@ module Warden::Mixins::Common
12
12
  request.cookie_jar
13
13
  end
14
14
  end
15
-
16
- class Warden::SessionSerializer
17
- def serialize(record)
18
- klass = record.class
19
- array = klass.serialize_into_session(record)
20
- array.unshift(klass.name)
21
- end
22
-
23
- def deserialize(keys)
24
- klass_name, *args = keys
25
-
26
- begin
27
- klass = ActiveSupport::Inflector.constantize(klass_name)
28
- if klass.respond_to? :serialize_from_session
29
- klass.serialize_from_session(*args)
30
- else
31
- Rails.logger.warn "[Devise] Stored serialized class #{klass_name} seems not to be Devise enabled anymore. Did you do that on purpose?"
32
- nil
33
- end
34
- rescue NameError => e
35
- if e.message =~ /uninitialized constant/
36
- Rails.logger.debug "[Devise] Trying to deserialize invalid class #{klass_name}"
37
- nil
38
- else
39
- raise
40
- end
41
- end
42
- end
43
- end
@@ -100,7 +100,7 @@ module Devise
100
100
 
101
101
  # Extract a hash with attributes:values from the http params.
102
102
  def http_auth_hash
103
- keys = [authentication_keys.first, :password]
103
+ keys = [http_authentication_key, :password]
104
104
  Hash[*keys.zip(decode_credentials).flatten]
105
105
  end
106
106
 
@@ -134,24 +134,27 @@ module Devise
134
134
  parse_authentication_key_values(request_values, request_keys)
135
135
  end
136
136
 
137
- # Holds the authentication keys.
138
137
  def authentication_keys
139
138
  @authentication_keys ||= mapping.to.authentication_keys
140
139
  end
141
140
 
142
- # Holds request keys.
141
+ def http_authentication_key
142
+ @http_authentication_key ||= mapping.to.http_authentication_key || case authentication_keys
143
+ when Array then authentication_keys.first
144
+ when Hash then authentication_keys.keys.first
145
+ end
146
+ end
147
+
143
148
  def request_keys
144
149
  @request_keys ||= mapping.to.request_keys
145
150
  end
146
151
 
147
- # Returns values from the request object.
148
152
  def request_values
149
153
  keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
150
154
  values = keys.map { |k| self.request.send(k) }
151
155
  Hash[keys.zip(values)]
152
156
  end
153
157
 
154
- # Parse authentication keys considering if they should be enforced or not.
155
158
  def parse_authentication_key_values(hash, keys)
156
159
  keys.each do |key, enforce|
157
160
  value = hash[key].presence
@@ -7,13 +7,22 @@ module Devise
7
7
  #
8
8
  # http://myapp.example.com/?user_token=SECRET
9
9
  #
10
- # For HTTP, you can pass the token as username and blank password. Since some clients may require
11
- # a password, you can pass "X" as password and it will simply be ignored.
10
+ # For headers, you can use basic authentication passing the token as username and
11
+ # blank password. Since some clients may require a password, you can pass "X" as
12
+ # password and it will simply be ignored.
13
+ #
14
+ # You may also pass the token using the Token authentication mechanism provided
15
+ # by Rails: http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
16
+ # The token options are stored in request.env['devise.token_options']
12
17
  class TokenAuthenticatable < Authenticatable
13
18
  def store?
14
19
  super && !mapping.to.skip_session_storage.include?(:token_auth)
15
20
  end
16
21
 
22
+ def valid?
23
+ super || valid_for_token_auth?
24
+ end
25
+
17
26
  def authenticate!
18
27
  resource = mapping.to.find_for_token_authentication(authentication_hash)
19
28
  return fail(:invalid_token) unless resource
@@ -36,7 +45,33 @@ module Devise
36
45
  false
37
46
  end
38
47
 
39
- # Try both scoped and non scoped keys.
48
+ # Check if the model accepts this strategy as token authenticatable.
49
+ def token_authenticatable?
50
+ mapping.to.http_authenticatable?(:token_options)
51
+ end
52
+
53
+ # Check if this is strategy is valid for token authentication by:
54
+ #
55
+ # * Validating if the model allows http token authentication;
56
+ # * If the http auth token exists;
57
+ # * If all authentication keys are present;
58
+ #
59
+ def valid_for_token_auth?
60
+ token_authenticatable? && auth_token.present? && with_authentication_hash(:token_auth, token_auth_hash)
61
+ end
62
+
63
+ # Extract the auth token from the request
64
+ def auth_token
65
+ @auth_token ||= ActionController::HttpAuthentication::Token.token_and_options(request)
66
+ end
67
+
68
+ # Extract a hash with attributes:values from the auth_token
69
+ def token_auth_hash
70
+ request.env['devise.token_options'] = auth_token.last
71
+ { authentication_keys.first => auth_token.first }
72
+ end
73
+
74
+ # Try both scoped and non scoped keys
40
75
  def params_auth_hash
41
76
  if params[scope].kind_of?(Hash) && params[scope].has_key?(authentication_keys.first)
42
77
  params[scope]
@@ -1,3 +1,3 @@
1
1
  module Devise
2
- VERSION = "2.2.3".freeze
2
+ VERSION = "2.2.4".freeze
3
3
  end
@@ -18,7 +18,7 @@ module Devise
18
18
  public_task :copy_views
19
19
  end
20
20
 
21
- # TODO: Add this to Rails itslef
21
+ # TODO: Add this to Rails itself
22
22
  module ClassMethods
23
23
  def hide!
24
24
  Rails::Generators.hide_namespace self.namespace
@@ -36,7 +36,13 @@ module Devise
36
36
  protected
37
37
 
38
38
  def view_directory(name, _target_path = nil)
39
- directory name.to_s, _target_path || "#{target_path}/#{name}"
39
+ directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
40
+ if scope
41
+ content.gsub "devise/shared/links", "#{scope}/shared/links"
42
+ else
43
+ content
44
+ end
45
+ end
40
46
  end
41
47
 
42
48
  def target_path
@@ -48,10 +48,14 @@ Devise.setup do |config|
48
48
  # enable it only for database (email + password) authentication.
49
49
  # config.params_authenticatable = true
50
50
 
51
- # Tell if authentication through HTTP Basic Auth is enabled. False by default.
51
+ # Tell if authentication through HTTP Auth is enabled. False by default.
52
52
  # It can be set to an array that will enable http authentication only for the
53
53
  # given strategies, for example, `config.http_authenticatable = [:token]` will
54
- # enable it only for token authentication.
54
+ # enable it only for token authentication. The supported strategies are:
55
+ # :database = Support basic authentication with authentication key + password
56
+ # :token = Support basic authentication with token authentication key
57
+ # :token_options = Support token authentication with options as defined in
58
+ # http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
55
59
  # config.http_authenticatable = false
56
60
 
57
61
  # If http headers should be returned for AJAX requests. True by default.
@@ -125,7 +129,7 @@ Devise.setup do |config|
125
129
  config.password_length = 8..128
126
130
 
127
131
  # Email regex used to validate email formats. It simply asserts that
128
- # an one (and only one) @ exists in the given string. This is mainly
132
+ # one (and only one) @ exists in the given string. This is mainly
129
133
  # to give user feedback and not to assert the e-mail validity.
130
134
  # config.email_regexp = /\A[^@]+@[^@]+\z/
131
135
 
@@ -175,7 +179,9 @@ Devise.setup do |config|
175
179
  # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
176
180
  # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
177
181
  # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
178
- # REST_AUTH_SITE_KEY to pepper)
182
+ # REST_AUTH_SITE_KEY to pepper).
183
+ #
184
+ # Require the `devise-encryptable` gem when using anything other than bcrypt
179
185
  # config.encryptor = :sha512
180
186
 
181
187
  # ==> Configuration for :token_authenticatable
@@ -22,6 +22,6 @@
22
22
 
23
23
  <h3>Cancel my account</h3>
24
24
 
25
- <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
25
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %></p>
26
26
 
27
27
  <%= link_to "Back", :back %>
@@ -0,0 +1,32 @@
1
+ require 'test_helper'
2
+
3
+ class PasswordsControllerTest < ActionController::TestCase
4
+ tests Devise::PasswordsController
5
+ include Devise::TestHelpers
6
+
7
+ def setup
8
+ request.env["devise.mapping"] = Devise.mappings[:user]
9
+
10
+ @user = create_user
11
+ @user.send_reset_password_instructions
12
+ end
13
+
14
+ def put_update_with_params
15
+ put :update, "user" => {
16
+ "reset_password_token" => @user.reset_password_token, "password" => "123456", "password_confirmation" => "123456"
17
+ }
18
+ end
19
+
20
+ test 'redirect to after_sign_in_path_for if after_resetting_password_path_for is not overridden' do
21
+ put_update_with_params
22
+ assert_redirected_to "http://test.host/"
23
+ end
24
+
25
+ test 'redirect accordingly if after_resetting_password_path_for is overridden' do
26
+ custom_path = "http://custom.path/"
27
+ Devise::PasswordsController.any_instance.stubs(:after_resetting_password_path_for).with(@user).returns(custom_path)
28
+
29
+ put_update_with_params
30
+ assert_redirected_to custom_path
31
+ end
32
+ end
@@ -80,9 +80,9 @@ class FailureTest < ActiveSupport::TestCase
80
80
 
81
81
  test 'setup a default message' do
82
82
  call_failure
83
- assert_match /You are being/, @response.last.body
84
- assert_match /redirected/, @response.last.body
85
- assert_match /users\/sign_in/, @response.last.body
83
+ assert_match(/You are being/, @response.last.body)
84
+ assert_match(/redirected/, @response.last.body)
85
+ assert_match(/users\/sign_in/, @response.last.body)
86
86
  end
87
87
 
88
88
  test 'works for any navigational format' do
@@ -8,14 +8,17 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
8
8
  test "Assert all views are properly created with no params" do
9
9
  run_generator
10
10
  assert_files
11
+ assert_shared_links
11
12
  end
12
13
 
13
- test "Assert all views are properly created with scope param param" do
14
+ test "Assert all views are properly created with scope param" do
14
15
  run_generator %w(users)
15
16
  assert_files "users"
17
+ assert_shared_links "users"
16
18
 
17
19
  run_generator %w(admins)
18
20
  assert_files "admins"
21
+ assert_shared_links "admins"
19
22
  end
20
23
 
21
24
  test "Assert views with simple form" do
@@ -49,4 +52,16 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
49
52
  assert_file "app/views/#{scope}/shared/_links.erb"
50
53
  assert_file "app/views/#{scope}/unlocks/new.html.erb"
51
54
  end
55
+
56
+ def assert_shared_links(scope = nil)
57
+ scope = "devise" if scope.nil?
58
+ link = /<%= render \"#{scope}\/shared\/links\" %>/
59
+
60
+ assert_file "app/views/#{scope}/passwords/edit.html.erb", link
61
+ assert_file "app/views/#{scope}/passwords/new.html.erb", link
62
+ assert_file "app/views/#{scope}/confirmations/new.html.erb", link
63
+ assert_file "app/views/#{scope}/registrations/new.html.erb", link
64
+ assert_file "app/views/#{scope}/sessions/new.html.erb", link
65
+ assert_file "app/views/#{scope}/unlocks/new.html.erb", link
66
+ end
52
67
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class DeviseHelperTest < ActionController::IntegrationTest
3
+ class DeviseHelperTest < ActionDispatch::IntegrationTest
4
4
  setup do
5
5
  model_labels = { :models => { :user => "utilisateur" } }
6
6
 
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class AuthenticationSanityTest < ActionController::IntegrationTest
3
+ class AuthenticationSanityTest < ActionDispatch::IntegrationTest
4
4
  test 'home should be accessible without sign in' do
5
5
  visit '/'
6
6
  assert_response :success
@@ -134,7 +134,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
134
134
  end
135
135
  end
136
136
 
137
- class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
137
+ class AuthenticationRoutesRestrictions < ActionDispatch::IntegrationTest
138
138
  test 'not signed in should not be able to access private route (authenticate denied)' do
139
139
  get private_path
140
140
  assert_redirected_to new_admin_session_path
@@ -254,7 +254,7 @@ class AuthenticationRoutesRestrictions < ActionController::IntegrationTest
254
254
  end
255
255
  end
256
256
 
257
- class AuthenticationRedirectTest < ActionController::IntegrationTest
257
+ class AuthenticationRedirectTest < ActionDispatch::IntegrationTest
258
258
  test 'redirect from warden shows sign in or sign up message' do
259
259
  get admins_path
260
260
 
@@ -317,7 +317,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
317
317
  end
318
318
  end
319
319
 
320
- class AuthenticationSessionTest < ActionController::IntegrationTest
320
+ class AuthenticationSessionTest < ActionDispatch::IntegrationTest
321
321
  test 'destroyed account is signed out' do
322
322
  sign_in_as_user
323
323
  get '/users'
@@ -333,22 +333,34 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
333
333
  assert_equal "Cart", @controller.user_session[:cart]
334
334
  end
335
335
 
336
- test 'does not explode when invalid user class is stored in session' do
337
- klass = User
338
- paths = ActiveSupport::Dependencies.autoload_paths.dup
339
-
336
+ test 'does not explode when class name is still stored in session' do
337
+ # In order to test that old sessions do not break with the new scoped
338
+ # deserialization, we need to serialize the session the old way. This is
339
+ # done by removing the newly used scoped serialization method
340
+ # (#user_serialize) and bringing back the old uncsoped #serialize method
341
+ # that includes the record's class name in the serialization.
340
342
  begin
343
+ Warden::SessionSerializer.class_eval do
344
+ alias_method :original_serialize, :serialize
345
+ alias_method :original_user_serialize, :user_serialize
346
+ remove_method :user_serialize
347
+
348
+ def serialize(record)
349
+ klass = record.class
350
+ array = klass.serialize_into_session(record)
351
+ array.unshift(klass.name)
352
+ end
353
+ end
354
+
341
355
  sign_in_as_user
342
356
  assert warden.authenticated?(:user)
343
-
344
- Object.send :remove_const, :User
345
- ActiveSupport::Dependencies.autoload_paths.clear
346
-
347
- visit "/users"
348
- assert_not warden.authenticated?(:user)
349
357
  ensure
350
- Object.const_set(:User, klass)
351
- ActiveSupport::Dependencies.autoload_paths.replace(paths)
358
+ Warden::SessionSerializer.class_eval do
359
+ alias_method :serialize, :original_serialize
360
+ remove_method :original_serialize
361
+ alias_method :user_serialize, :original_user_serialize
362
+ remove_method :original_user_serialize
363
+ end
352
364
  end
353
365
  end
354
366
 
@@ -364,7 +376,7 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
364
376
  end
365
377
  end
366
378
 
367
- class AuthenticationWithScopedViewsTest < ActionController::IntegrationTest
379
+ class AuthenticationWithScopedViewsTest < ActionDispatch::IntegrationTest
368
380
  test 'renders the scoped view if turned on and view is available' do
369
381
  swap Devise, :scoped_views => true do
370
382
  assert_raise Webrat::NotFoundError do
@@ -405,7 +417,7 @@ class AuthenticationWithScopedViewsTest < ActionController::IntegrationTest
405
417
  end
406
418
  end
407
419
 
408
- class AuthenticationOthersTest < ActionController::IntegrationTest
420
+ class AuthenticationOthersTest < ActionDispatch::IntegrationTest
409
421
  test 'handles unverified requests gets rid of caches' do
410
422
  swap UsersController, :allow_forgery_protection => true do
411
423
  post exhibit_user_url(1)
@@ -504,14 +516,26 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
504
516
  assert response.body.include? %(<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<user>)
505
517
  end
506
518
 
507
- test 'sign out with xml format returns ok response' do
519
+ test 'sign out with html redirects' do
520
+ sign_in_as_user
521
+ get destroy_user_session_path
522
+ assert_response :redirect
523
+ assert_current_url '/'
524
+
525
+ sign_in_as_user
526
+ get destroy_user_session_path(:format => 'html')
527
+ assert_response :redirect
528
+ assert_current_url '/'
529
+ end
530
+
531
+ test 'sign out with xml format returns no content' do
508
532
  sign_in_as_user
509
533
  get destroy_user_session_path(:format => 'xml')
510
534
  assert_response :no_content
511
535
  assert_not warden.authenticated?(:user)
512
536
  end
513
537
 
514
- test 'sign out with json format returns empty json response' do
538
+ test 'sign out with json format returns no content' do
515
539
  sign_in_as_user
516
540
  get destroy_user_session_path(:format => 'json')
517
541
  assert_response :no_content
@@ -519,7 +543,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
519
543
  end
520
544
 
521
545
  test 'sign out with non-navigational format via XHR does not redirect' do
522
- swap Devise, :navigational_formats => ['*/*', :html] do
546
+ swap Devise, :navigational_formats => ['*/*', :html] do
523
547
  sign_in_as_user
524
548
  xml_http_request :get, destroy_user_session_path, {}, { "HTTP_ACCEPT" => "application/json,text/javascript,*/*" } # NOTE: Bug is triggered by combination of XHR and */*.
525
549
  assert_response :no_content
@@ -529,7 +553,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
529
553
 
530
554
  # Belt and braces ... Perhaps this test is not necessary?
531
555
  test 'sign out with navigational format via XHR does redirect' do
532
- swap Devise, :navigational_formats => ['*/*', :html] do
556
+ swap Devise, :navigational_formats => ['*/*', :html] do
533
557
  sign_in_as_user
534
558
  xml_http_request :get, destroy_user_session_path, {}, { "HTTP_ACCEPT" => "text/html,*/*" }
535
559
  assert_response :redirect
@@ -538,7 +562,7 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
538
562
  end
539
563
  end
540
564
 
541
- class AuthenticationKeysTest < ActionController::IntegrationTest
565
+ class AuthenticationKeysTest < ActionDispatch::IntegrationTest
542
566
  test 'missing authentication keys cause authentication to abort' do
543
567
  swap Devise, :authentication_keys => [:subdomain] do
544
568
  sign_in_as_user
@@ -555,7 +579,7 @@ class AuthenticationKeysTest < ActionController::IntegrationTest
555
579
  end
556
580
  end
557
581
 
558
- class AuthenticationRequestKeysTest < ActionController::IntegrationTest
582
+ class AuthenticationRequestKeysTest < ActionDispatch::IntegrationTest
559
583
  test 'request keys are used on authentication' do
560
584
  host! 'foo.bar.baz'
561
585
 
@@ -596,7 +620,7 @@ class AuthenticationRequestKeysTest < ActionController::IntegrationTest
596
620
  end
597
621
  end
598
622
 
599
- class AuthenticationSignOutViaTest < ActionController::IntegrationTest
623
+ class AuthenticationSignOutViaTest < ActionDispatch::IntegrationTest
600
624
  def sign_in!(scope)
601
625
  sign_in_as_admin(:visit => send("new_#{scope}_session_path"))
602
626
  assert warden.authenticated?(scope)
@@ -650,3 +674,26 @@ class AuthenticationSignOutViaTest < ActionController::IntegrationTest
650
674
  assert warden.authenticated?(:sign_out_via_delete_or_post)
651
675
  end
652
676
  end
677
+
678
+ class DoubleAuthenticationRedirectTest < ActionDispatch::IntegrationTest
679
+ test 'signed in as user redirects when visiting user sign in page' do
680
+ sign_in_as_user
681
+ get new_user_session_path(:format => :html)
682
+ assert_redirected_to '/'
683
+ end
684
+
685
+ test 'signed in as admin redirects when visiting admin sign in page' do
686
+ sign_in_as_admin
687
+ get new_admin_session_path(:format => :html)
688
+ assert_redirected_to '/admin_area/home'
689
+ end
690
+
691
+ test 'signed in as both user and admin redirects when visiting admin sign in page' do
692
+ sign_in_as_user
693
+ sign_in_as_admin
694
+ get new_user_session_path(:format => :html)
695
+ assert_redirected_to '/'
696
+ get new_admin_session_path(:format => :html)
697
+ assert_redirected_to '/admin_area/home'
698
+ end
699
+ end