Be sure to expire cached devise data after sign in, closes #1411

This commit is contained in:
José Valim 2011-11-05 20:09:46 -02:00
parent 0439c35198
commit 1bace6df4e
4 changed files with 34 additions and 12 deletions

View File

@ -8,10 +8,12 @@
* Fix bug where logs did not show 401 as status code
* Change paranoid settings to behave as success instead of as failure
* Fix bug where activation messages were shown first than the credentials error message
* Be sure to expire cached devise data after sign in
* deprecation
* redirect_location is deprecated, please use after_sign_in_path_for
* after_sign_in_path_for now redirects to session[scope_return_to] if any value is stored in it
* expire_session_data_after_sign_in! is deprecated in favor of expire_devise_cached_data!
== 1.4.9

View File

@ -20,7 +20,7 @@ class Devise::RegistrationsController < ApplicationController
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :inactive_signed_up, :reason => inactive_reason(resource) if is_navigational_format?
expire_session_data_after_sign_in!
expire_devise_cached_data!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
@ -64,7 +64,7 @@ class Devise::RegistrationsController < ApplicationController
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
def cancel
expire_session_data_after_sign_in!
expire_devise_cached_data!
redirect_to new_registration_path(resource_name)
end

View File

@ -88,7 +88,7 @@ module Devise
# Return true if the given scope is signed in session. If no scope given, return
# true if any scope is signed in. Does not run authentication hooks.
def signed_in?(scope=nil)
[ scope || Devise.mappings.keys ].flatten.any? do |scope|
[ scope || Devise.mappings.keys ].flatten.any? do |scope|
warden.authenticate?(:scope => scope)
end
end
@ -107,13 +107,13 @@ module Devise
# sign_in @user # sign_in(resource)
# sign_in @user, :event => :authentication # sign_in(resource, options)
# sign_in @user, :bypass => true # sign_in(resource, options)
#
#
def sign_in(resource_or_scope, *args)
options = args.extract_options!
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource = args.last || resource_or_scope
expire_session_data_after_sign_in!
expire_devise_cached_data!
if options[:bypass]
warden.session_serializer.store(resource, scope)
@ -226,6 +226,11 @@ module Devise
after_sign_in_path_for(resource)
end
def expire_session_data_after_sign_in!
ActiveSupport::Deprecation.warn "expire_session_data_after_sign_in! is deprecated. Please use expire_devise_cached_data! instead which also clears up cached instance variables.", caller
expire_devise_cached_data!
end
# Sign out a user and tries to redirect to the url specified by
# after_sign_out_path_for.
def sign_out_and_redirect(resource_or_scope)
@ -234,20 +239,26 @@ module Devise
redirect_to after_sign_out_path_for(scope)
end
# A hook called to expire session data after sign up/in. All keys
# stored under "devise." namespace are removed after sign in.
def expire_session_data_after_sign_in!
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
end
# 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!
Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
expire_devise_cached_variables!
super # call the default behaviour which resets the session
end
# A hook called to expire data after sign in.
def expire_devise_cached_data!
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
expire_devise_cached_variables!
end
private
def expire_devise_cached_variables!
Devise.mappings.each { |_,m| instance_variable_set("@current_#{m.name}", nil) }
end
end
end
end

View File

@ -114,6 +114,15 @@ class ControllerAuthenticatableTest < ActionController::TestCase
assert @controller.sign_in(user)
end
test 'sign in clears up any signed in user' do
@controller.instance_variable_set(:@current_user, :example)
user = User.new
@mock_warden.expects(:user).returns(user)
@mock_warden.expects(:set_user).never
@controller.sign_in(user)
assert_equal nil, @controller.instance_variable_get(:@current_user)
end
test 'sign in again when the user is already in only if force is given' do
user = User.new
@mock_warden.expects(:user).returns(user)