1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Create after_sign_in_path_for and after_sign_out_path_for hooks and sign_in_and_redirect and sign_out_and_redirect helpers.

This commit is contained in:
José Valim 2009-11-19 11:16:31 -02:00
parent 977b7f206a
commit d445b4beb9
8 changed files with 99 additions and 51 deletions

View file

@ -1,3 +1,8 @@
* enhancements
* [#37] Create after_sign_in_path_for and after_sign_out_path_for hooks to be
overwriten in ApplicationController
* Create sign_in_and_redirect and sign_out_and_redirect helpers
== 0.5.3
* bug fix

View file

@ -103,33 +103,15 @@ The next step after setting up your model is to configure your routes for devise
map.devise_for :users
This is going to look inside you User model and create the needed routes:
This is going to look inside you User model and create a set of needed routes (you can see them by running `rake routes`).
# Session routes for Authenticatable (default)
new_user_session GET /users/sign_in {:controller=>"sessions", :action=>"new"}
user_session POST /users/sign_in {:controller=>"sessions", :action=>"create"}
destroy_user_session GET /users/sign_out {:controller=>"sessions", :action=>"destroy"}
# Password routes for Recoverable, if User model has :recoverable configured
new_user_password GET /users/password/new(.:format) {:controller=>"passwords", :action=>"new"}
edit_user_password GET /users/password/edit(.:format) {:controller=>"passwords", :action=>"edit"}
user_password PUT /users/password(.:format) {:controller=>"passwords", :action=>"update"}
POST /users/password(.:format) {:controller=>"passwords", :action=>"create"}
# Confirmation routes for Confirmable, if User model has :confirmable configured
new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"confirmations", :action=>"new"}
user_confirmation GET /users/confirmation(.:format) {:controller=>"confirmations", :action=>"show"}
POST /users/confirmation(.:format) {:controller=>"confirmations", :action=>"create"}
You can run the routes rake task to verify what routes are being created by devise.
There are also some options available for configuring your routes, as :class_name (to set the class for that route), :as and :path_names, where the last two have the same meaning as in routes. The available :path_names are:
There are also some options available for configuring your routes, as :class_name (to set the class for that route), :as and :path_names, where the last two have the same meaning as in common routes. The available :path_names are:
map.devise_for :users, :as => "usuarios", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
Be sure to check devise_for documentation for detailed description.
== Controller filters
== Controller filters and helpers
Devise is gonna create some helpers to use inside your controllers and views. To setup a controller that needs user authentication, just add this before_filter:
@ -151,7 +133,9 @@ After signing in a user, confirming it's account or updating it's password, devi
map.root :controller => 'home'
You also need to setup default url options for the mailer, if you are using confirmable or recoverable. Here's is the configuration for development:
You can also overwrite after_sign_in_path_for and after_sign_out_path_for to customize better your redirect hooks.
Finally, if you are using confirmable or recoverable, you also need to setup default url options for the mailer. Here's is the configuration for development:
DeviseMailer.sender = "no-reply@yourapp.com"
config.action_mailer.default_url_options = { :host => 'localhost:3000' }

View file

@ -23,9 +23,8 @@ class ConfirmationsController < ApplicationController
self.resource = resource_class.confirm!(:confirmation_token => params[:confirmation_token])
if resource.errors.empty?
sign_in(resource_name, resource)
set_flash_message :success, :confirmed
redirect_to home_or_root_path
sign_in_and_redirect(resource_name, resource)
else
render :new
end

View file

@ -31,9 +31,8 @@ class PasswordsController < ApplicationController
self.resource = resource_class.reset_password!(params[resource_name])
if resource.errors.empty?
sign_in(resource_name, resource)
set_flash_message :success, :updated
redirect_to home_or_root_path
sign_in_and_redirect(resource_name, resource)
else
render :edit
end

View file

@ -15,7 +15,7 @@ class SessionsController < ApplicationController
def create
if authenticate(resource_name)
set_flash_message :success, :signed_in
redirect_back_or_to home_or_root_path
sign_in_and_redirect(resource_name)
else
set_now_flash_message :failure, warden.message || :invalid
build_resource
@ -26,8 +26,7 @@ class SessionsController < ApplicationController
# GET /resource/sign_out
def destroy
set_flash_message :success, :signed_out if signed_in?(resource_name)
sign_out(resource_name)
redirect_to root_path
sign_out_and_redirect(resource_name)
end
end

View file

@ -90,6 +90,53 @@ module Devise
session.delete(:"#{scope}.return_to")
end
# The default url to be used after signing in. This is used by all Devise
# controllers and you can overwrite it in your ApplicationController to
# provide a custom hook for a custom resource.
#
# By default, it first tries to find a resource_root_path, otherwise it
# uses the root path. For a user scope, you can define the default url in
# the following way:
#
# map.user_root '/users', :controller => 'users' # creates user_root_path
#
# map.resources :users do |users|
# users.root # creates user_root_path
# end
#
# If none of these are defined, root_path is used.
def after_sign_in_path_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
home_path = :"#{scope}_root_path"
respond_to?(home_path, true) ? send(home_path) : root_path
end
# The default to be used after signing out. This is used by all Devise
# controllers and you can overwrite it in your ApplicationController to
# provide a custom hook for a custom resource.
#
# By default is the root_path.
def after_sign_out_path_for(resource_or_scope)
root_path
end
# Sign in an user and tries to redirect first to the stored location and
# then to the url specified by after_sign_in_path_for.
#
# If just a symbol is given, consider that the user was already signed in
# through other means and just perform the redirection.
def sign_in_and_redirect(*args)
sign_in(*args) unless args.one? && args.first.is_a?(Symbol)
redirect_to stored_location_for(args.first) || after_sign_in_path_for(args.first)
end
# Sign out an user and tries to redirect to the url specified by
# after_sign_out_path_for.
def sign_out_and_redirect(resource_or_scope)
sign_out(resource_or_scope)
redirect_to after_sign_out_path_for(resource_or_scope)
end
# Define authentication filters and accessor helpers based on mappings.
# These filters should be used inside the controllers as before_filters,
# so you can control the scope of the user who should be signed in to

View file

@ -44,27 +44,6 @@ module Devise
protected
# Redirects to stored uri before signing in or the default path and clear
# return to.
def redirect_back_or_to(default)
redirect_to(stored_location_for(resource_name) || default)
end
# Checks for the existence of the resource root path. If it exists,
# returns it, otherwise returns the default root_path.
# Used after authenticating a user, confirming it's account or updating
# it's password, so we are able to redirect to scoped root paths.
# Examples (for a user scope):
# map.user_root '/users', :controller => 'users' # creates user_root_path
#
# map.namespace :users do |users|
# users.root # creates user_root_path
# end
def home_or_root_path
home_path = :"#{resource_name}_root_path"
respond_to?(home_path, true) ? send(home_path) : root_path
end
# Checks whether it's a devise mapped resource or not.
def is_devise_resource? #:nodoc:
raise ActionController::UnknownAction unless devise_mapping && devise_mapping.allows?(controller_name)
@ -88,7 +67,7 @@ module Devise
# Example:
# before_filter :require_no_authentication, :only => :new
def require_no_authentication
redirect_to home_or_root_path if warden.authenticated?(resource_name)
redirect_to after_sign_in_path_for(resource_name) if warden.authenticated?(resource_name)
end
# Sets the flash message with :key, using I18n. By default you are able

View file

@ -121,6 +121,42 @@ class ControllerAuthenticableTest < ActionController::TestCase
assert_nil @controller.session[:"user.return_to"]
end
test 'after sign in path defaults to root path if none by was specified for the given scope' do
assert_equal root_path, @controller.after_sign_in_path_for(:user)
end
test 'after sign in path defaults to the scoped root path' do
assert_equal admin_root_path, @controller.after_sign_in_path_for(:admin)
end
test 'after sign out path defaults to the root path' do
assert_equal root_path, @controller.after_sign_out_path_for(:admin)
assert_equal root_path, @controller.after_sign_out_path_for(:user)
end
test 'sign in and redirect uses the stored location' do
user = User.new
@controller.session[:"user.return_to"] = "/foo.bar"
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
@controller.expects(:redirect_to).with("/foo.bar")
@controller.sign_in_and_redirect(user)
end
test 'sign in and redirect uses the configured after sign in path' do
admin = Admin.new
@mock_warden.expects(:set_user).with(admin, :scope => :admin).returns(true)
@controller.expects(:redirect_to).with(admin_root_path)
@controller.sign_in_and_redirect(admin)
end
test 'sign out and redirect uses the configured after sign out path' do
@mock_warden.expects(:user).with(:admin).returns(true)
@mock_warden.expects(:logout).with(: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)
end
test 'is not a devise controller' do
assert_not @controller.devise_controller?
end