From f4ceecece416bb71fef8c43a8a0d126222747bc8 Mon Sep 17 00:00:00 2001 From: Matt Jones + Tony Schneider Date: Mon, 4 Mar 2013 12:18:20 -0500 Subject: [PATCH] Allow explicit configuration of http auth key - Fix basic auth case in which authorized_keys is configured as hash - Duplicate existing functionality when http_auth_key is not explicitly set --- lib/devise.rb | 4 ++++ lib/devise/models/authenticatable.rb | 6 +++++- lib/devise/strategies/authenticatable.rb | 10 +++++++++- test/integration/http_authenticatable_test.rb | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lib/devise.rb b/lib/devise.rb index 094467c5..87e1f307 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -51,6 +51,10 @@ module Devise mattr_accessor :stretches @@stretches = 10 + # The default key used when authenticating over http auth. + mattr_accessor :http_auth_key + @@http_auth_key = nil + # Keys used when authenticating a user. mattr_accessor :authentication_keys @@authentication_keys = [ :email ] diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index f1d08dd1..89820725 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -10,6 +10,9 @@ module Devise # # * +authentication_keys+: parameters used for authentication. By default [:email]. # + # * +http_auth_key+: map the username passed via HTTP Auth to this parameter. Defaults to + # the first element in +authentication_keys+. + # # * +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. @@ -194,7 +197,8 @@ module Devise module ClassMethods Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys, - :case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage) + :case_insensitive_keys, :http_authenticatable, :params_authenticatable, :skip_session_storage, + :http_auth_key) def serialize_into_session(record) [record.to_key, record.authenticatable_salt] diff --git a/lib/devise/strategies/authenticatable.rb b/lib/devise/strategies/authenticatable.rb index e57ba9b3..3efcbe67 100644 --- a/lib/devise/strategies/authenticatable.rb +++ b/lib/devise/strategies/authenticatable.rb @@ -100,7 +100,7 @@ module Devise # Extract a hash with attributes:values from the http params. def http_auth_hash - keys = [authentication_keys.first, :password] + keys = [http_auth_key, :password] Hash[*keys.zip(decode_credentials).flatten] end @@ -139,6 +139,14 @@ module Devise @authentication_keys ||= mapping.to.authentication_keys end + def http_auth_key + @http_auth_key ||= mapping.to.http_auth_key + @http_auth_key ||= case authentication_keys + when Array then authentication_keys.first + when Hash then authentication_keys.keys.first + end + end + # Holds request keys. def request_keys @request_keys ||= mapping.to.request_keys diff --git a/test/integration/http_authenticatable_test.rb b/test/integration/http_authenticatable_test.rb index de910190..889a9bee 100644 --- a/test/integration/http_authenticatable_test.rb +++ b/test/integration/http_authenticatable_test.rb @@ -62,6 +62,24 @@ class HttpAuthenticationTest < ActionDispatch::IntegrationTest end end + test 'it uses appropriate authentication_keys when configured with hash' do + swap Devise, :authentication_keys => { :username => false, :email => false } do + sign_in_as_new_user_with_http("usertest") + assert_response :success + assert_match 'user@test.com', response.body + assert warden.authenticated?(:user) + end + end + + test 'it uses the appropriate key when configured explicitly' do + swap Devise, :authentication_keys => { :email => false, :username => false }, :http_auth_key => :username do + sign_in_as_new_user_with_http("usertest") + assert_response :success + assert_match 'user@test.com', response.body + assert warden.authenticated?(:user) + end + end + test 'test request with oauth2 header doesnt get mistaken for basic authentication' do swap Devise, :http_authenticatable => true do add_oauth2_header