Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added a couple of helpers to help sign up and delete account tasks.

  • Loading branch information...
commit 05fc5712e35407366c08b1adafad7f6547f1e381 1 parent 4f6dfef
@josevalim josevalim authored
View
4 CHANGELOG.rdoc
@@ -1,3 +1,7 @@
+* enhancements
+ * [#28] Improved sign_in and sign_out helpers to accepts resources
+ * [#28] Added stored_location_for as a helper
+
== 0.5.1
* enhancements
View
50 lib/devise/controllers/filters.rb
@@ -49,17 +49,45 @@ def signed_in?(scope)
warden.authenticated?(scope)
end
- # Set the warden user with the scope, signing in the resource automatically,
- # without running hooks.
- def sign_in(scope, resource)
+ # Sign in an user that already was authenticated. This helper is useful for logging
+ # users in after sign up.
+ #
+ # Examples:
+ #
+ # sign_in :user, @user # sign_in(scope, resource)
+ # sign_in @user # sign_in(resource)
+ #
+ def sign_in(resource_or_scope, resource=nil)
+ scope ||= find_devise_scope(resource_or_scope)
+ resource ||= resource_or_scope
warden.set_user(resource, :scope => scope)
end
- # Sign out based on scope.
- def sign_out(scope, *args)
+ # Sign out a given user or scope. This helper is useful for signing out an user
+ # after deleting accounts.
+ #
+ # Examples:
+ #
+ # sign_out :user # sign_out(scope)
+ # sign_out @user # sign_out(resource)
+ #
+ def sign_out(resource_or_scope)
+ scope = find_devise_scope(resource_or_scope)
warden.user(scope) # Without loading user here, before_logout hook is not called
warden.raw_session.inspect # Without this inspect here. The session does not clear.
- warden.logout(scope, *args)
+ warden.logout(scope)
+ end
+
+ # Returns and delete the url stored in the session for the given scope. Useful
+ # for giving redirect backs after sign up:
+ #
+ # Example:
+ #
+ # redirect_to stored_location_for(:user) || root_path
+ #
+ def stored_location_for(resource_or_scope)
+ scope = find_devise_scope(resource_or_scope)
+ session.delete(:"#{scope}.return_to")
end
# Define authentication filters and accessor helpers based on mappings.
@@ -106,6 +134,16 @@ def #{mapping}_session
METHODS
end
+ protected
+
+ def find_devise_scope(resource_or_scope)
+ if resource_or_scope.is_a?(Symbol)
+ resource_or_scope
+ else
+ Devise::Mapping.find_by_class!(resource_or_scope.class).name
+ end
+ end
+
end
end
end
View
13 lib/devise/controllers/helpers.rb
@@ -45,18 +45,7 @@ def devise_controller?
# Redirects to stored uri before signing in or the default path and clear
# return to.
def redirect_back_or_to(default)
- redirect_to(return_to || default)
- clear_return_to
- end
-
- # Access to scoped stored uri
- def return_to
- session[:"#{resource_name}.return_to"]
- end
-
- # Clear scoped stored uri
- def clear_return_to
- session[:"#{resource_name}.return_to"] = nil
+ redirect_to(stored_location_for(resource_name) || default)
end
# Checks for the existence of the resource root path. If it exists,
View
12 lib/devise/mapping.rb
@@ -34,6 +34,18 @@ def self.find_by_path(path)
nil
end
+ # Find a mapping by a given class. It takes into account single table inheritance as well.
+ def self.find_by_class(klass)
+ Devise.mappings.values.find { |m| return m if klass <= m.to }
+ end
+
+ # Find by class but raising an error in case it can't be found.
+ def self.find_by_class!(klass)
+ mapping = find_by_class(klass)
+ raise "Could not find a valid mapping for #{klass}" unless mapping
+ mapping
+ end
+
# Default url options which can be used as prefix.
def self.default_url_options
{}
View
49 test/controllers/filters_test.rb
@@ -14,11 +14,13 @@ def path
end
class ControllerAuthenticableTest < ActionController::TestCase
+ tests MockController
def setup
@controller = MockController.new
@mock_warden = OpenStruct.new
@controller.env = { 'warden' => @mock_warden }
+ @controller.session = {}
end
test 'setup warden' do
@@ -47,12 +49,6 @@ def setup
@controller.current_user
end
- test 'proxy logout to warden' do
- @mock_warden.expects(:user).with(:user).returns(true)
- @mock_warden.expects(:logout).with(:user).returns(true)
- @controller.sign_out(:user)
- end
-
test 'proxy user_authenticate! to authenticate with user scope' do
@mock_warden.expects(:authenticate!).with(:scope => :user)
@controller.authenticate_user!
@@ -83,11 +79,48 @@ def setup
@controller.admin_session
end
- test 'sign in automatically proxy to set user on warden' do
- @mock_warden.expects(:set_user).with(user = mock, :scope => :user).returns(true)
+ test 'sign in proxy to set_user on warden' do
+ user = User.new
+ @mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
@controller.sign_in(:user, user)
end
+ test 'sign in accepts a resource as argument' do
+ user = User.new
+ @mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
+ @controller.sign_in(user)
+ end
+
+ test 'sign out proxy to logout on warden' do
+ @mock_warden.expects(:user).with(:user).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(:user).returns(true)
+ @mock_warden.expects(:logout).with(:user).returns(true)
+ @controller.sign_out(User.new)
+ end
+
+ test 'stored location for returns the location for a given scope' do
+ assert_nil @controller.stored_location_for(:user)
+ @controller.session[:"user.return_to"] = "/foo.bar"
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
+ end
+
+ test 'stored location for accepts a resource as argument' do
+ assert_nil @controller.stored_location_for(:user)
+ @controller.session[:"user.return_to"] = "/foo.bar"
+ assert_equal "/foo.bar", @controller.stored_location_for(User.new)
+ end
+
+ test 'stored location cleans information after reading' do
+ @controller.session[:"user.return_to"] = "/foo.bar"
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
+ assert_nil @controller.session[:"user.return_to"]
+ end
+
test 'is not a devise controller' do
assert_not @controller.devise_controller?
end
Please sign in to comment.
Something went wrong with that request. Please try again.