Add request_keys support. Closes #401.
This commit is contained in:
parent
fc37436a24
commit
b2066cc229
|
@ -7,6 +7,7 @@
|
|||
* sign_out_via is available in the router to configure the method used for sign out (by github.com/martinrehfeld)
|
||||
* Improved Ajax requests handling in failure app (by github.com/spastorino)
|
||||
* Add reply-to to e-mail headers by default
|
||||
* Add request_keys to easily use request specific values (like subdomain) in authentication
|
||||
|
||||
* bugfix
|
||||
* after_sign_in_path_for always receives a resource
|
||||
|
|
|
@ -68,6 +68,10 @@ module Devise
|
|||
mattr_accessor :authentication_keys
|
||||
@@authentication_keys = [ :email ]
|
||||
|
||||
# Request keys used when authenticating an user.
|
||||
mattr_accessor :request_keys
|
||||
@@request_keys = []
|
||||
|
||||
# If http authentication is enabled by default.
|
||||
mattr_accessor :http_authenticatable
|
||||
@@http_authenticatable = false
|
||||
|
|
|
@ -10,6 +10,14 @@ module Devise
|
|||
#
|
||||
# * +authentication_keys+: parameters used for authentication. By default [:email].
|
||||
#
|
||||
# * +request_keys+: parameters from the request object used for authentication.
|
||||
# By specifying a symbol (which should be a request method), it will automatically be
|
||||
# passed to find_for_authentication method and considered in your model lookup.
|
||||
#
|
||||
# For instance, if you set :request_keys to [:subdomain], :subdomain will be considered
|
||||
# as key on authentication. This can also be a hash where the value is a boolean expliciting
|
||||
# if the value is required or not.
|
||||
#
|
||||
# * +http_authenticatable+: if this model allows http authentication. By default true.
|
||||
# It also accepts an array specifying the strategies that should allow http.
|
||||
#
|
||||
|
@ -66,7 +74,7 @@ module Devise
|
|||
end
|
||||
|
||||
module ClassMethods
|
||||
Devise::Models.config(self, :authentication_keys, :http_authenticatable, :params_authenticatable)
|
||||
Devise::Models.config(self, :authentication_keys, :request_keys, :http_authenticatable, :params_authenticatable)
|
||||
|
||||
def params_authenticatable?(strategy)
|
||||
params_authenticatable.is_a?(Array) ?
|
||||
|
|
|
@ -101,10 +101,12 @@ module Devise
|
|||
end
|
||||
|
||||
# Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
|
||||
def with_authentication_hash(hash)
|
||||
self.authentication_hash = hash.slice(*authentication_keys)
|
||||
self.password = hash[:password]
|
||||
authentication_keys.all?{ |k| authentication_hash[k].present? }
|
||||
def with_authentication_hash(auth_values)
|
||||
self.authentication_hash = {}
|
||||
self.password = auth_values[:password]
|
||||
|
||||
parse_authentication_key_values(auth_values, authentication_keys) &&
|
||||
parse_authentication_key_values(request_values, request_keys)
|
||||
end
|
||||
|
||||
# Holds the authentication keys.
|
||||
|
@ -112,6 +114,33 @@ module Devise
|
|||
@authentication_keys ||= mapping.to.authentication_keys
|
||||
end
|
||||
|
||||
# Holds request keys.
|
||||
def request_keys
|
||||
@request_keys ||= mapping.to.request_keys
|
||||
end
|
||||
|
||||
# Returns values from the request object.
|
||||
def request_values
|
||||
keys = request_keys.respond_to?(:keys) ? request_keys.keys : request_keys
|
||||
keys.inject({}) do |hash, key|
|
||||
hash[key] = self.request.send(key)
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
# Parse authentication keys considering if they should be enforced or not.
|
||||
def parse_authentication_key_values(hash, keys)
|
||||
keys.each do |key, enforce|
|
||||
value = hash[key].presence
|
||||
if value
|
||||
self.authentication_hash[key] = value
|
||||
else
|
||||
return false unless enforce == false
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
# Holds the authenticatable name for this class. Devise::Strategies::DatabaseAuthenticatable
|
||||
# becomes simply :database.
|
||||
def authenticatable_name
|
||||
|
|
|
@ -20,8 +20,17 @@ Devise.setup do |config|
|
|||
# authenticating an user, both parameters are required. Remember that those
|
||||
# parameters are used only when authenticating and not when retrieving from
|
||||
# session. If you need permissions, you should implement that in a before filter.
|
||||
# You can also supply hash where the value is a boolean expliciting if authentication
|
||||
# should be aborted or not if the value is not present. By default is empty.
|
||||
# config.authentication_keys = [ :email ]
|
||||
|
||||
# Configure parameters from the request object used for authentication. Each entry
|
||||
# given should be a request method and it will automatically be passed to
|
||||
# find_for_authentication method and considered in your model lookup. For instance,
|
||||
# if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
|
||||
# The same considerations mentioned for authentication_keys also apply to request_keys.
|
||||
# config.request_keys = []
|
||||
|
||||
# Tell if authentication through request.params is enabled. True by default.
|
||||
# config.params_authenticatable = true
|
||||
|
||||
|
|
|
@ -333,6 +333,47 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
|||
end
|
||||
end
|
||||
|
||||
class AuthenticationRequestKeysTest < ActionController::IntegrationTest
|
||||
test 'request keys are used on authentication' do
|
||||
host! 'foo.bar.baz'
|
||||
|
||||
swap Devise, :request_keys => [:subdomain] do
|
||||
User.expects(:find_for_authentication).with(:subdomain => 'foo', :email => 'user@test.com').returns(create_user)
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'invalid request keys raises NoMethodError' do
|
||||
swap Devise, :request_keys => [:unknown_method] do
|
||||
assert_raise NoMethodError do
|
||||
sign_in_as_user
|
||||
end
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'blank request keys cause authentication to abort' do
|
||||
host! 'test.com'
|
||||
|
||||
swap Devise, :request_keys => [:subdomain] do
|
||||
sign_in_as_user
|
||||
assert_contain "Invalid email or password."
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'blank request keys cause authentication to abort unless if marked as not required' do
|
||||
host! 'test.com'
|
||||
|
||||
swap Devise, :request_keys => { :subdomain => false } do
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationSignOutViaTest < ActionController::IntegrationTest
|
||||
def sign_in!(scope)
|
||||
sign_in_as_user(:visit => send("new_#{scope}_session_path"))
|
||||
|
|
Loading…
Reference in New Issue