mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Allow :path_prefix to be given to devise_for.
This commit is contained in:
parent
e4cc18cdc3
commit
4debe4080b
9 changed files with 95 additions and 46 deletions
|
@ -1,17 +1,11 @@
|
||||||
class SessionsController < ApplicationController
|
class SessionsController < ApplicationController
|
||||||
include Devise::Controllers::Helpers
|
include Devise::Controllers::Helpers
|
||||||
|
|
||||||
# Maps the messages types that comes from warden to a flash type.
|
|
||||||
WARDEN_MESSAGES = {
|
|
||||||
:unauthenticated => :success,
|
|
||||||
:unconfirmed => :failure
|
|
||||||
}
|
|
||||||
|
|
||||||
before_filter :require_no_authentication, :only => [ :new, :create ]
|
before_filter :require_no_authentication, :only => [ :new, :create ]
|
||||||
|
|
||||||
# GET /resource/sign_in
|
# GET /resource/sign_in
|
||||||
def new
|
def new
|
||||||
WARDEN_MESSAGES.each do |message, type|
|
Devise::FLASH_MESSAGES.each do |message, type|
|
||||||
set_now_flash_message type, message if params.key?(message)
|
set_now_flash_message type, message if params.key?(message)
|
||||||
end
|
end
|
||||||
build_resource
|
build_resource
|
||||||
|
|
|
@ -11,9 +11,19 @@ module Devise
|
||||||
STRATEGIES = [:rememberable, :authenticatable].freeze
|
STRATEGIES = [:rememberable, :authenticatable].freeze
|
||||||
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
||||||
|
|
||||||
|
# Maps the messages types that comes from warden to a flash type.
|
||||||
|
FLASH_MESSAGES = {
|
||||||
|
:unauthenticated => :success,
|
||||||
|
:unconfirmed => :failure
|
||||||
|
}
|
||||||
|
|
||||||
# Models configuration
|
# Models configuration
|
||||||
mattr_accessor :pepper, :stretches, :remember_for, :confirm_within
|
mattr_accessor :pepper, :stretches, :remember_for, :confirm_within
|
||||||
|
|
||||||
|
# Mappings
|
||||||
|
mattr_accessor :mappings
|
||||||
|
self.mappings = {}
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Default way to setup Devise. Run script/generate devise_install to create
|
# Default way to setup Devise. Run script/generate devise_install to create
|
||||||
# a fresh initializer with all configuration values.
|
# a fresh initializer with all configuration values.
|
||||||
|
@ -56,5 +66,4 @@ module Devise
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'devise/warden'
|
require 'devise/warden'
|
||||||
require 'devise/mapping'
|
|
||||||
require 'devise/rails'
|
require 'devise/rails'
|
||||||
|
|
|
@ -31,7 +31,7 @@ module Devise
|
||||||
|
|
||||||
# Attempt to find the mapped route for devise based on request path
|
# Attempt to find the mapped route for devise based on request path
|
||||||
def devise_mapping
|
def devise_mapping
|
||||||
@devise_mapping ||= Devise.find_mapping_by_path(request.path)
|
@devise_mapping ||= Devise::Mapping.find_by_path(request.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -19,7 +19,7 @@ module Devise
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_path = if mapping = Devise.mappings[scope]
|
redirect_path = if mapping = Devise.mappings[scope]
|
||||||
"/#{mapping.as}/#{mapping.path_names[:sign_in]}"
|
"#{mapping.parsed_path}/#{mapping.path_names[:sign_in]}"
|
||||||
else
|
else
|
||||||
"/#{default_url}"
|
"/#{default_url}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,13 +22,28 @@ module Devise
|
||||||
# # is the modules included in the class
|
# # is the modules included in the class
|
||||||
#
|
#
|
||||||
class Mapping #:nodoc:
|
class Mapping #:nodoc:
|
||||||
attr_reader :name, :as, :path_names
|
attr_reader :name, :as, :path_names, :path_prefix
|
||||||
|
|
||||||
|
# Loop through all mappings looking for a map that matches with the requested
|
||||||
|
# path (ie /users/sign_in). If a path prefix is given, it's taken into account.
|
||||||
|
def self.find_by_path(path)
|
||||||
|
Devise.mappings.each_value do |mapping|
|
||||||
|
route = path.split("/")[mapping.as_position]
|
||||||
|
return mapping if mapping.as == route.to_sym
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(name, options)
|
def initialize(name, options)
|
||||||
|
options.assert_valid_keys(:class_name, :as, :path_names, :singular, :path_prefix)
|
||||||
|
|
||||||
@as = (options[:as] || name).to_sym
|
@as = (options[:as] || name).to_sym
|
||||||
@klass = (options[:class_name] || name.to_s.classify).to_s
|
@klass = (options[:class_name] || name.to_s.classify).to_s
|
||||||
@name = (options[:singular] || name.to_s.singularize).to_sym
|
@name = (options[:singular] || name.to_s.singularize).to_sym
|
||||||
@path_names = options[:path_names] || {}
|
@path_names = options[:path_names] || {}
|
||||||
|
@path_prefix = options[:path_prefix] || ""
|
||||||
|
@path_prefix << "/" unless @path_prefix[-1] == ?/
|
||||||
|
|
||||||
setup_path_names
|
setup_path_names
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,6 +65,23 @@ module Devise
|
||||||
self.for.include?(CONTROLLERS[controller.to_sym])
|
self.for.include?(CONTROLLERS[controller.to_sym])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return in which position in the path prefix devise should find the as mapping.
|
||||||
|
def as_position
|
||||||
|
self.path_prefix.count("/")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the raw path using path_prefix and as.
|
||||||
|
def raw_path
|
||||||
|
path_prefix + as.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the parsed path. If you need meta information in your path_prefix,
|
||||||
|
# you should overwrite this method to use it. The only information supported
|
||||||
|
# by default is I18n.locale.
|
||||||
|
def parsed_path
|
||||||
|
raw_path.gsub(":locale", I18n.locale.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
# Create magic predicates for verifying what module is activated by this map.
|
# Create magic predicates for verifying what module is activated by this map.
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
|
@ -75,21 +107,4 @@ module Devise
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mattr_accessor :mappings
|
|
||||||
self.mappings = {}
|
|
||||||
|
|
||||||
# Loop through all mappings looking for a map that matches with the requested
|
|
||||||
# path (ie /users/sign_in). The important part here is the key :users. If no
|
|
||||||
# map is found just returns nil.
|
|
||||||
def self.find_mapping_by_path(path)
|
|
||||||
route = path.split("/")[1]
|
|
||||||
return nil unless route
|
|
||||||
|
|
||||||
route = route.to_sym
|
|
||||||
mappings.each do |key, map|
|
|
||||||
return map if map.as == route.to_sym
|
|
||||||
end
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,40 +60,42 @@ module ActionController::Routing
|
||||||
#
|
#
|
||||||
# map.devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
|
# map.devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
|
||||||
#
|
#
|
||||||
|
# * :path_prefix => the path prefix to be used in all routes. Only :locale is supported as dynamic prefix:
|
||||||
|
#
|
||||||
|
# map.devise_for :users, :path_prefix => "/:locale"
|
||||||
|
#
|
||||||
def devise_for(*resources)
|
def devise_for(*resources)
|
||||||
options = resources.extract_options!
|
options = resources.extract_options!
|
||||||
|
|
||||||
resources.map!(&:to_sym)
|
resources.map!(&:to_sym)
|
||||||
options.assert_valid_keys(:class_name, :as, :path_names, :singular)
|
|
||||||
|
|
||||||
resources.each do |resource|
|
resources.each do |resource|
|
||||||
mapping = Devise::Mapping.new(resource, options)
|
mapping = Devise::Mapping.new(resource, options)
|
||||||
Devise.mappings[mapping.name] = mapping
|
Devise.mappings[mapping.name] = mapping
|
||||||
|
|
||||||
mapping.for.each do |strategy|
|
with_options(:path_prefix => mapping.raw_path, :name_prefix => "#{mapping.name}_") do |routes|
|
||||||
send(strategy, mapping) if self.respond_to?(strategy, true)
|
mapping.for.each do |strategy|
|
||||||
|
send(strategy, routes, mapping) if self.respond_to?(strategy, true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def authenticatable(mapping)
|
def authenticatable(routes, mapping)
|
||||||
with_options(:controller => 'sessions', :path_prefix => mapping.as) do |session|
|
routes.with_options(:controller => 'sessions', :name_prefix => nil) do |session|
|
||||||
session.send(:"new_#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'new', :conditions => { :method => :get })
|
session.send(:"new_#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'new', :conditions => { :method => :get })
|
||||||
session.send(:"#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'create', :conditions => { :method => :post })
|
session.send(:"#{mapping.name}_session", mapping.path_names[:sign_in], :action => 'create', :conditions => { :method => :post })
|
||||||
session.send(:"destroy_#{mapping.name}_session", mapping.path_names[:sign_out], :action => 'destroy', :conditions => { :method => :get })
|
session.send(:"destroy_#{mapping.name}_session", mapping.path_names[:sign_out], :action => 'destroy', :conditions => { :method => :get })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def recoverable(mapping)
|
def recoverable(routes, mapping)
|
||||||
resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password],
|
routes.resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password]
|
||||||
:path_prefix => mapping.as, :name_prefix => "#{mapping.name}_"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def confirmable(mapping)
|
def confirmable(routes, mapping)
|
||||||
resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation],
|
routes.resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation]
|
||||||
:path_prefix => mapping.as, :name_prefix => "#{mapping.name}_"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,12 @@ class MappingTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'return mapping by path' do
|
test 'return mapping by path' do
|
||||||
assert_nil Devise.find_mapping_by_path("/foo/bar")
|
assert_nil Devise::Mapping.find_by_path("/foo/bar")
|
||||||
assert_equal Devise.mappings[:user], Devise.find_mapping_by_path("/users/session")
|
assert_equal Devise.mappings[:user], Devise::Mapping.find_by_path("/users/session")
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'return mapping by customized path' do
|
test 'return mapping by customized path' do
|
||||||
assert_equal Devise.mappings[:admin], Devise.find_mapping_by_path("/admin_area/session")
|
assert_equal Devise.mappings[:admin], Devise::Mapping.find_by_path("/admin_area/session")
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'return default path names' do
|
test 'return default path names' do
|
||||||
|
@ -55,6 +55,31 @@ class MappingTest < ActiveSupport::TestCase
|
||||||
assert_equal 'verification', mapping.path_names[:confirmation]
|
assert_equal 'verification', mapping.path_names[:confirmation]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'has an empty path as default path prefix' do
|
||||||
|
mapping = Devise.mappings[:account]
|
||||||
|
assert_equal '/', mapping.path_prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'allow path prefix to be configured' do
|
||||||
|
mapping = Devise.mappings[:manager]
|
||||||
|
assert_equal '/:locale/', mapping.path_prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'retrieve as from the proper position' do
|
||||||
|
assert_equal 1, Devise.mappings[:account].as_position
|
||||||
|
assert_equal 2, Devise.mappings[:manager].as_position
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'raw path is returned' do
|
||||||
|
assert_equal '/account', Devise.mappings[:account].raw_path
|
||||||
|
assert_equal '/:locale/organizers', Devise.mappings[:manager].raw_path
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'parsed path is returned' do
|
||||||
|
assert_equal '/account', Devise.mappings[:account].parsed_path
|
||||||
|
assert_equal '/en/organizers', Devise.mappings[:manager].parsed_path
|
||||||
|
end
|
||||||
|
|
||||||
test 'magic predicates' do
|
test 'magic predicates' do
|
||||||
mapping = Devise.mappings[:user]
|
mapping = Devise.mappings[:user]
|
||||||
assert mapping.authenticatable?
|
assert mapping.authenticatable?
|
||||||
|
|
|
@ -4,7 +4,7 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
map.devise_for :account, :path_names => {
|
map.devise_for :account, :path_names => {
|
||||||
:sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification'
|
:sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification'
|
||||||
}
|
}
|
||||||
map.devise_for :organizers, :singular => 'manager'
|
map.devise_for :organizers, :singular => 'manager', :path_prefix => '/:locale'
|
||||||
|
|
||||||
map.resources :users, :only => :index
|
map.resources :users, :only => :index
|
||||||
map.resources :admins, :only => :index
|
map.resources :admins, :only => :index
|
||||||
|
|
|
@ -69,7 +69,11 @@ class MapRoutingTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test 'map organizer with custom singular name' do
|
test 'map organizer with custom singular name' do
|
||||||
assert_recognizes({:controller => 'passwords', :action => 'new'}, 'organizers/password/new')
|
assert_recognizes({:controller => 'passwords', :action => 'new', :locale => "en"}, '/en/organizers/password/new')
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'map organizer with path prefix' do
|
||||||
|
assert_recognizes({:controller => 'sessions', :action => 'new', :locale => "en"}, '/en/organizers/sign_in')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue