From 76314560470b07c4a5d88dad17c354e37846b6db Mon Sep 17 00:00:00 2001 From: Mac Martine Date: Thu, 16 Jun 2011 21:24:20 -0700 Subject: [PATCH] Added support for Devise routes to honor constraints. --- lib/devise/mapping.rb | 9 ++++++++- lib/devise/rails/routes.rb | 11 ++++++----- test/rails_app/config/routes.rb | 9 ++++++++- test/routes_test.rb | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/devise/mapping.rb b/lib/devise/mapping.rb index 0b302d52..863d562c 100644 --- a/lib/devise/mapping.rb +++ b/lib/devise/mapping.rb @@ -63,6 +63,9 @@ module Devise @path_names = Hash.new { |h,k| h[k] = k.to_s } @path_names.merge!(:registration => "") @path_names.merge!(options[:path_names] || {}) + + @constraints = Hash.new { |h,k| h[k] = k.to_s } + @constraints.merge!(options[:constraints] || {}) @sign_out_via = options[:sign_out_via] || Devise.sign_out_via end @@ -96,7 +99,11 @@ module Devise def fullpath "/#{@path_prefix}/#{@path}".squeeze("/") end - + + def constraints + @constraints + end + # Create magic predicates for verifying what module is activated by this map. # Example: # diff --git a/lib/devise/rails/routes.rb b/lib/devise/rails/routes.rb index 8068c5b5..eb182bc1 100644 --- a/lib/devise/rails/routes.rb +++ b/lib/devise/rails/routes.rb @@ -159,6 +159,7 @@ module ActionDispatch::Routing options[:module] ||= @scope[:module] if @scope[:module].present? options[:path_prefix] ||= @scope[:path] if @scope[:path].present? options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {}) + options[:constraints] = (@scope[:constraints] || {}).merge(options[:constraints] || {}) resources.map!(&:to_sym) @@ -185,7 +186,7 @@ module ActionDispatch::Routing devise_scope mapping.name do yield if block_given? - with_devise_exclusive_scope mapping.fullpath, mapping.name do + with_devise_exclusive_scope mapping.fullpath, mapping.name, mapping.constraints do routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) } end end @@ -286,12 +287,12 @@ module ActionDispatch::Routing @scope[:path] = path end - def with_devise_exclusive_scope(new_path, new_as) #:nodoc: - old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module] - @scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil + def with_devise_exclusive_scope(new_path, new_as, new_constraints) #:nodoc: + old_as, old_path, old_module, old_constraints = @scope[:as], @scope[:path], @scope[:module], @scope[:constraints] + @scope[:as], @scope[:path], @scope[:module], @scope[:constraints] = new_as, new_path, nil, new_constraints yield ensure - @scope[:as], @scope[:path], @scope[:module] = old_as, old_path, old_module + @scope[:as], @scope[:path], @scope[:module], @scope[:constraints] = old_as, old_path, old_module, old_constraints end def raise_no_devise_method_error!(klass) #:nodoc: diff --git a/test/rails_app/config/routes.rb b/test/rails_app/config/routes.rb index b6768d7b..c56ceb0e 100644 --- a/test/rails_app/config/routes.rb +++ b/test/rails_app/config/routes.rb @@ -27,7 +27,14 @@ Rails.application.routes.draw do authenticate(:admin) do match "/private", :to => "home#private", :as => :private end - + + # Routes for constraints testing + devise_for :admin, :path => "headquarters", :constraints => {:host => /192\.168\.1\.\d\d\d/} + + constraints(:host => /192\.168\.1\.\d\d\d/) do + devise_for :admin, :path => "homebase" + end + # Other routes for routing_test.rb devise_for :reader, :class_name => "User", :only => :passwords diff --git a/test/routes_test.rb b/test/routes_test.rb index c02a4e70..ec3d0a21 100644 --- a/test/routes_test.rb +++ b/test/routes_test.rb @@ -176,6 +176,20 @@ class CustomizedRoutingTest < ActionController::TestCase assert_recognizes({:controller => 'devise/sessions', :action => 'destroy'}, {:path => '/sign_out_via/delete_or_posts/sign_out', :method => :get}) end end + + test 'map with constraints defined in hash' do + assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'http://192.168.1.100/headquarters/sign_up', :method => :get}) + assert_raise ActionController::RoutingError do + assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'http://10.0.0.100/headquarters/sign_up', :method => :get}) + end + end + + test 'map with constraints defined in block' do + assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'http://192.168.1.100/homebase/sign_up', :method => :get}) + assert_raise ActionController::RoutingError do + assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'http://10.0.0.100//homebase/sign_up', :method => :get}) + end + end end class ScopedRoutingTest < ActionController::TestCase