Merge pull request #1147 from sj26/master

Authenticated Route Constraints
This commit is contained in:
José Valim 2011-06-23 05:29:17 -07:00
commit f43a7c4f24
7 changed files with 120 additions and 4 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1 @@
Admin dashboard

View File

@ -0,0 +1 @@
Join

View File

@ -0,0 +1 @@
User dashboard

View File

@ -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/}