diff --git a/Gemfile.lock b/Gemfile.lock index 1d94a041..be73f4c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,7 +5,7 @@ PATH bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) railties (~> 3.1) - warden (~> 1.1.1) + warden (~> 1.2.1) GEM remote: http://rubygems.org/ @@ -135,7 +135,7 @@ GEM polyglot polyglot (>= 0.3.1) tzinfo (0.3.33) - warden (1.1.1) + warden (1.2.1) rack (>= 1.0) webrat (0.7.2) nokogiri (>= 1.2.0) diff --git a/devise.gemspec b/devise.gemspec index c54c886d..4df95625 100644 --- a/devise.gemspec +++ b/devise.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.test_files = `git ls-files -- test/*`.split("\n") s.require_paths = ["lib"] - s.add_dependency("warden", "~> 1.1.1") + s.add_dependency("warden", "~> 1.2.1") s.add_dependency("orm_adapter", "~> 0.1") s.add_dependency("bcrypt-ruby", "~> 3.0") s.add_dependency("railties", "~> 3.1") diff --git a/lib/devise/controllers/helpers.rb b/lib/devise/controllers/helpers.rb index 8f847c24..0c147b06 100644 --- a/lib/devise/controllers/helpers.rb +++ b/lib/devise/controllers/helpers.rb @@ -126,8 +126,8 @@ module Devise end # Sign out a given user or scope. This helper is useful for signing out a user - # after deleting accounts. Returns true if there was a logout and false if there is no user logged in - # on the referred scope + # after deleting accounts. Returns true if there was a logout and false if there + # is no user logged in on the referred scope # # Examples: # @@ -141,6 +141,7 @@ module Devise warden.raw_session.inspect # Without this inspect here. The session does not clear. warden.logout(scope) + warden.clear_strategies_cache!(:scope => scope) instance_variable_set(:"@current_#{scope}", nil) !!user @@ -149,12 +150,14 @@ module Devise # Sign out all active users or scopes. This helper is useful for signing out all roles # in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout # and false if there was no user logged in on all scopes. - def sign_out_all_scopes + def sign_out_all_scopes(lock=true) users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) } warden.raw_session.inspect warden.logout expire_devise_cached_variables! + warden.clear_strategies_cache! + warden.lock! if lock users.any? end @@ -253,8 +256,7 @@ module Devise # Overwrite Rails' handle unverified request to sign out all scopes, # clear run strategies and remove cached variables. def handle_unverified_request - sign_out_all_scopes - warden.clear_strategies_cache! + sign_out_all_scopes(false) request.env["devise.skip_storage"] = true expire_devise_cached_variables! super # call the default behaviour which resets the session diff --git a/test/controllers/helpers_test.rb b/test/controllers/helpers_test.rb index 7610b187..8036b546 100644 --- a/test/controllers/helpers_test.rb +++ b/test/controllers/helpers_test.rb @@ -139,30 +139,27 @@ class ControllerAuthenticatableTest < ActionController::TestCase assert_equal nil, @controller.instance_variable_get(:@current_admin) end - test 'sign out clears up any signed in user by scope' do + test 'sign out logs out and clears up any signed in user by scope' do user = User.new @mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(user) @mock_warden.expects(:logout).with(:user).returns(true) + @mock_warden.expects(:clear_strategies_cache!).with(:scope => :user).returns(true) @controller.instance_variable_set(:@current_user, user) @controller.sign_out(:user) assert_equal nil, @controller.instance_variable_get(:@current_user) end - - test 'sign out proxy to logout on warden' do - @mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(true) - @mock_warden.expects(:logout).with(:user).returns(true) - @controller.sign_out(:user) - end test 'sign out accepts a resource as argument' do @mock_warden.expects(:user).with(:scope => :user, :run_callbacks => false).returns(true) @mock_warden.expects(:logout).with(:user).returns(true) + @mock_warden.expects(:clear_strategies_cache!).with(:scope => :user).returns(true) @controller.sign_out(User.new) end test 'sign out without args proxy to sign out all scopes' do @mock_warden.expects(:user).times(Devise.mappings.size) @mock_warden.expects(:logout).with().returns(true) + @mock_warden.expects(:clear_strategies_cache!).with().returns(true) @controller.sign_out end @@ -232,6 +229,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase swap Devise, :sign_out_all_scopes => false do @mock_warden.expects(:user).with(:scope => :admin, :run_callbacks => false).returns(true) @mock_warden.expects(:logout).with(:admin).returns(true) + @mock_warden.expects(:clear_strategies_cache!).with(:scope => :admin).returns(true) @controller.expects(:redirect_to).with(admin_root_path) @controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end" @controller.sign_out_and_redirect(:admin) @@ -242,6 +240,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase swap Devise, :sign_out_all_scopes => true do @mock_warden.expects(:user).times(Devise.mappings.size) @mock_warden.expects(:logout).with().returns(true) + @mock_warden.expects(:clear_strategies_cache!).with().returns(true) @controller.expects(:redirect_to).with(admin_root_path) @controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end" @controller.sign_out_and_redirect(:admin)