Skip to content

Commit

Permalink
Add support of several devise scopes in one controller
Browse files Browse the repository at this point in the history
Closes #64
  • Loading branch information
Vladimir Lyzo authored and gonzalo-bulnes committed May 24, 2014
1 parent 0ed9c30 commit d5ea8d0
Showing 1 changed file with 42 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,34 @@ module ActsAsTokenAuthenticationHandlerMethods
ActionController::Base.send :include, Devise::Controllers::SignInOut if Rails.env.test?
end

def authenticate_entity!
def authenticate_entity!(entity_class)
# Caution: entity should be a singular camel-cased name but could be pluralized or underscored.
self.method("authenticate_#{@@entity.name.singularize.underscore}!".to_sym).call
self.method("authenticate_#{entity_class.name.singularize.underscore}!".to_sym).call
end


# For this example, we are simply using token authentication
# via parameters. However, anyone could use Rails's token
# authentication features to get the token from a header.
def authenticate_entity_from_token!
def authenticate_entity_from_token!(entity_class)
# Set the authentication token params if not already present,
# see http://stackoverflow.com/questions/11017348/rails-api-authentication-by-headers-token
params_token_name = "#{@@entity.name.singularize.underscore}_token".to_sym
params_email_name = "#{@@entity.name.singularize.underscore}_email".to_sym
if token = params[params_token_name].blank? && request.headers[header_token_name]
params_token_name = "#{entity_class.name.singularize.underscore}_token".to_sym
params_email_name = "#{entity_class.name.singularize.underscore}_email".to_sym
if token = params[params_token_name].blank? && request.headers[header_token_name(entity_class)]
params[params_token_name] = token
end
if email = params[params_email_name].blank? && request.headers[header_email_name]
if email = params[params_email_name].blank? && request.headers[header_email_name(entity_class)]
params[params_email_name] = email
end

email = params[params_email_name].presence
# See https://github.com/ryanb/cancan/blob/1.6.10/lib/cancan/controller_resource.rb#L108-L111
entity = nil
if @@entity.respond_to? "find_by"
entity = email && @@entity.find_by(email: email)
elsif @@entity.respond_to? "find_by_email"
entity = email && @@entity.find_by_email(email)
if entity_class.respond_to? "find_by"
entity = email && entity_class.find_by(email: email)
elsif entity_class.respond_to? "find_by_email"
entity = email && entity_class.find_by_email(email)
end

# Notice how we use Devise.secure_compare to compare the token
Expand All @@ -63,26 +63,22 @@ def authenticate_entity_from_token!
end

# Private: Return the name of the header to watch for the token authentication param
def header_token_name
if SimpleTokenAuthentication.header_names["#{@@entity.name.singularize.underscore}".to_sym].presence
SimpleTokenAuthentication.header_names["#{@@entity.name.singularize.underscore}".to_sym][:authentication_token]
def header_token_name(entity_class)
if SimpleTokenAuthentication.header_names["#{entity_class.name.singularize.underscore}".to_sym].presence
SimpleTokenAuthentication.header_names["#{entity_class.name.singularize.underscore}".to_sym][:authentication_token]
else
"X-#{@@entity.name.singularize.camelize}-Token"
"X-#{entity_class.name.singularize.camelize}-Token"
end
end

# Private: Return the name of the header to watch for the email param
def header_email_name
if SimpleTokenAuthentication.header_names["#{@@entity.name.singularize.underscore}".to_sym].presence
SimpleTokenAuthentication.header_names["#{@@entity.name.singularize.underscore}".to_sym][:email]
def header_email_name(entity_class)
if SimpleTokenAuthentication.header_names["#{entity_class.name.singularize.underscore}".to_sym].presence
SimpleTokenAuthentication.header_names["#{entity_class.name.singularize.underscore}".to_sym][:email]
else
"X-#{@@entity.name.singularize.camelize}-Email"
"X-#{entity_class.name.singularize.camelize}-Email"
end
end

def self.set_entity entity
@@entity = entity
end
end

module ActsAsTokenAuthenticationHandler
Expand All @@ -100,19 +96,37 @@ module ClassMethods
def acts_as_token_authentication_handler_for(entity, options = {})
options = { fallback_to_devise: true }.merge(options)

SimpleTokenAuthentication::ActsAsTokenAuthenticationHandlerMethods.set_entity entity
include SimpleTokenAuthentication::ActsAsTokenAuthenticationHandlerMethods

# This is our new function that comes before Devise's one
before_filter :authenticate_entity_from_token!, options.slice(:only, :except)
# This is Devise's authentication
options[:fallback_to_devise] && before_filter(:authenticate_entity!, options.slice(:only, :except))
define_acts_as_token_authentication_helpers_for(entity)

authenticate_method = if options[:fallback_to_devise]
:"authenticate_#{entity.name.singularize.underscore}_from_token!"
else
:"authenticate_#{entity.name.singularize.underscore}_from_token"
end
before_filter authenticate_method, options.slice(:only, :except)
end

def acts_as_token_authentication_handler
ActiveSupport::Deprecation.warn "`acts_as_token_authentication_handler()` is deprecated and may be removed from future releases, use `acts_as_token_authentication_handler_for(User)` instead.", caller
acts_as_token_authentication_handler_for User
end

def define_acts_as_token_authentication_helpers_for(entity_class)
entity_underscored = entity_class.name.singularize.underscore

class_eval <<-METHODS, __FILE__, __LINE__ + 1
def authenticate_#{entity_underscored}_from_token
authenticate_entity_from_token!(#{entity_class.name})
end
def authenticate_#{entity_underscored}_from_token!
authenticate_entity_from_token!(#{entity_class.name})
authenticate_entity!(#{entity_class.name})
end
METHODS
end
end
end
end
Expand Down

0 comments on commit d5ea8d0

Please sign in to comment.