diff --git a/lib/devise/rails/routes.rb b/lib/devise/rails/routes.rb index eb182bc1..a55df494 100644 --- a/lib/devise/rails/routes.rb +++ b/lib/devise/rails/routes.rb @@ -129,9 +129,9 @@ module ActionDispatch::Routing # end # # ==== Adding custom actions to override controllers - # - # You can pass a block to devise_for that will add any routes defined in the block to Devise's - # list of known actions. This is important if you add a custom action to a controller that + # + # You can pass a block to devise_for that will add any routes defined in the block to Devise's + # list of known actions. This is important if you add a custom action to a controller that # overrides an out of the box Devise controller. # For example: # @@ -209,6 +209,50 @@ module ActionDispatch::Routing end end + # Allow you to route based on whether a scope is authenticated. You + # can optionally specify which scope. + # + # authenticated :admin do + # root :to => 'admin/dashboard#show' + # end + # + # authenticated do + # root :to => 'dashboard#show' + # end + # + # root :to => 'landing#show' + # + def authenticated(scope=nil) + constraint = lambda do |request| + request.env["warden"].authenticate? :scope => scope + end + + constraints(constraint) do + yield + end + end + + # Allow you to route based on whether a scope is *not* authenticated. + # You can optionally specify which scope. + # + # unauthenticated do + # as :user do + # root :to => 'devise/registrations#new' + # end + # end + # + # root :to => 'dashboard#show' + # + def unauthenticated(scope=nil) + constraint = lambda do |request| + not request.env["warden"].authenticate? :scope => scope + end + + constraints(constraint) do + yield + end + end + # Sets the devise scope to be used in the controller. If you have custom routes, # you are required to call this method (also aliased as :as) in order to specify # to which controller it is targetted. diff --git a/test/integration/authenticatable_test.rb b/test/integration/authenticatable_test.rb index febd98ac..ff834ad3 100644 --- a/test/integration/authenticatable_test.rb +++ b/test/integration/authenticatable_test.rb @@ -101,6 +101,54 @@ class AuthenticationSanityTest < ActionController::IntegrationTest assert_contain 'Private!' end + test 'signed in as admin should get admin dashboard' do + sign_in_as_admin + assert warden.authenticated?(:admin) + assert_not warden.authenticated?(:user) + + get dashboard_path + + assert_response :success + assert_template 'home/admin' + assert_contain 'Admin dashboard' + end + + test 'signed in as user should get user dashboard' do + sign_in_as_user + assert warden.authenticated?(:user) + assert_not warden.authenticated?(:admin) + + get dashboard_path + + assert_response :success + assert_template 'home/user' + assert_contain 'User dashboard' + end + + test 'not signed in should get no dashboard' do + assert_raises ActionController::RoutingError do + get dashboard_path + end + end + + test 'signed in user should not see join page' do + sign_in_as_user + assert warden.authenticated?(:user) + assert_not warden.authenticated?(:admin) + + assert_raises ActionController::RoutingError do + get join_path + end + end + + test 'not signed in should see join page' do + get join_path + + assert_response :success + assert_template 'home/join' + assert_contain 'Join' + end + test 'signed in as user should not be able to access admins actions' do sign_in_as_user assert warden.authenticated?(:user) diff --git a/test/rails_app/app/controllers/home_controller.rb b/test/rails_app/app/controllers/home_controller.rb index 148b73be..19a787bd 100644 --- a/test/rails_app/app/controllers/home_controller.rb +++ b/test/rails_app/app/controllers/home_controller.rb @@ -5,6 +5,15 @@ class HomeController < ApplicationController def private end + def user_dashboard + end + + def admin_dashboard + end + + def join + end + def set session["devise.foo_bar"] = "something" head :ok diff --git a/test/rails_app/app/views/home/admin_dashboard.html.erb b/test/rails_app/app/views/home/admin_dashboard.html.erb new file mode 100644 index 00000000..ad6e2462 --- /dev/null +++ b/test/rails_app/app/views/home/admin_dashboard.html.erb @@ -0,0 +1 @@ +Admin dashboard \ No newline at end of file diff --git a/test/rails_app/app/views/home/join.html.erb b/test/rails_app/app/views/home/join.html.erb new file mode 100644 index 00000000..a8d9133d --- /dev/null +++ b/test/rails_app/app/views/home/join.html.erb @@ -0,0 +1 @@ +Join \ No newline at end of file diff --git a/test/rails_app/app/views/home/user_dashboard.html.erb b/test/rails_app/app/views/home/user_dashboard.html.erb new file mode 100644 index 00000000..a54dcabf --- /dev/null +++ b/test/rails_app/app/views/home/user_dashboard.html.erb @@ -0,0 +1 @@ +User dashboard \ No newline at end of file diff --git a/test/rails_app/config/routes.rb b/test/rails_app/config/routes.rb index 32c7ae6a..b6c73eeb 100644 --- a/test/rails_app/config/routes.rb +++ b/test/rails_app/config/routes.rb @@ -27,7 +27,19 @@ Rails.application.routes.draw do authenticate(:admin) do match "/private", :to => "home#private", :as => :private end - + + authenticated :admin do + match "/dashboard", :to => "home#admin_dashboard" + end + + authenticated do + match "/dashboard", :to => "home#user_dashboard" + end + + unauthenticated do + match "/join", :to => "home#join" + end + # Routes for constraints testing devise_for :headquarters_admin, :class_name => "Admin", :path => "headquarters", :constraints => {:host => /192\.168\.1\.\d\d\d/}