1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00
heartcombo--devise/lib/devise/models/authenticatable.rb

169 lines
6.1 KiB
Ruby
Raw Normal View History

require 'devise/hooks/activatable'
module Devise
module Models
# Authenticatable module. Holds common settings for authentication.
#
2010-07-15 13:01:31 +02:00
# == Options
#
2010-07-15 13:01:31 +02:00
# Authenticatable adds the following options to devise_for:
#
2010-07-15 13:01:31 +02:00
# * +authentication_keys+: parameters used for authentication. By default [:email].
#
2010-09-21 11:45:44 +02:00
# * +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.
#
2010-07-15 13:01:31 +02:00
# * +http_authenticatable+: if this model allows http authentication. By default true.
# It also accepts an array specifying the strategies that should allow http.
#
2010-07-15 13:01:31 +02:00
# * +params_authenticatable+: if this model allows authentication through request params. By default true.
# It also accepts an array specifying the strategies that should allow params authentication.
#
# == active_for_authentication?
#
# Before authenticating a user and in each request, Devise checks if your model is active by
# calling model.active_for_authentication?. This method is overwriten by other devise modules. For instance,
# :confirmable overwrites .active_for_authentication? to only return true if your model was confirmed.
#
# You overwrite this method yourself, but if you do, don't forget to call super:
#
# def active_for_authentication?
# super && special_condition_is_valid?
# end
#
# Whenever active_for_authentication? returns false, Devise asks the reason why your model is inactive using
# the inactive_message method. You can overwrite it as well:
#
# def inactive_message
# special_condition_is_valid? ? super : :special_condition_is_not_valid
# end
#
module Authenticatable
extend ActiveSupport::Concern
2010-04-16 22:00:06 +02:00
included do
class_attribute :devise_modules, :instance_writer => false
self.devise_modules ||= []
end
# Check if the current object is valid for authentication. This method and
# find_for_authentication are the methods used in a Warden::Strategy to check
# if a model should be signed in or not.
#
# However, you should not overwrite this method, you should overwrite active_for_authentication?
# and inactive_message instead.
def valid_for_authentication?
if active_for_authentication?
block_given? ? yield : true
else
inactive_message
end
end
def active_for_authentication?
true
end
def inactive_message
:inactive
end
def authenticatable_salt
end
%w(to_xml to_json).each do |method|
class_eval <<-RUBY, __FILE__, __LINE__
def #{method}(options={})
if self.class.respond_to?(:accessible_attributes)
options = { :only => self.class.accessible_attributes.to_a }.merge(options || {})
super(options)
else
super
end
end
RUBY
end
module ClassMethods
2010-11-18 21:24:42 +01:00
Devise::Models.config(self, :authentication_keys, :request_keys, :case_insensitive_keys, :http_authenticatable, :params_authenticatable)
def params_authenticatable?(strategy)
params_authenticatable.is_a?(Array) ?
params_authenticatable.include?(strategy) : params_authenticatable
end
def http_authenticatable?(strategy)
http_authenticatable.is_a?(Array) ?
http_authenticatable.include?(strategy) : http_authenticatable
end
# Find first record based on conditions given (ie by the sign in form).
# Overwrite to add customized conditions, create a join, or maybe use a
# namedscope to filter records while authenticating.
# Example:
#
# def self.find_for_authentication(conditions={})
# conditions[:active] = true
# super
# end
#
def find_for_authentication(conditions)
2011-03-11 20:46:08 +01:00
filter_auth_params(conditions)
2011-03-15 12:52:53 +01:00
(case_insensitive_keys || []).each { |k| conditions[k].try(:downcase!) }
2010-10-10 17:51:12 +02:00
to_adapter.find_first(conditions)
end
2010-04-16 22:00:06 +02:00
# Find an initialize a record setting an error if it can't be found.
def find_or_initialize_with_error_by(attribute, value, error=:invalid) #:nodoc:
find_or_initialize_with_errors([attribute], { attribute => value }, error)
2010-04-16 22:00:06 +02:00
end
# Find an initialize a group of attributes based on a list of required attributes.
def find_or_initialize_with_errors(required_attributes, attributes, error=:invalid) #:nodoc:
2011-03-15 12:52:53 +01:00
(case_insensitive_keys || []).each { |k| attributes[k].try(:downcase!) }
2010-11-18 21:24:42 +01:00
attributes = attributes.slice(*required_attributes)
attributes.delete_if { |key, value| value.blank? }
if attributes.size == required_attributes.size
2011-03-11 20:46:08 +01:00
record = to_adapter.find_first(filter_auth_params(attributes))
end
unless record
record = new
required_attributes.each do |key|
2010-09-24 11:30:08 +02:00
value = attributes[key]
record.send("#{key}=", value)
record.errors.add(key, value.present? ? error : :blank)
end
end
record
end
2010-07-18 23:32:56 +02:00
2011-03-11 20:46:08 +01:00
protected
# Force keys to be string to avoid injection on mongoid related database.
def filter_auth_params(conditions)
conditions.each do |k, v|
conditions[k] = v.to_s
2011-03-16 05:52:53 -07:00
end if conditions.is_a?(Hash)
2011-03-11 20:46:08 +01:00
end
2010-07-18 23:32:56 +02:00
# Generate a token by looping and ensuring does not already exist.
def generate_token(column)
loop do
token = Devise.friendly_token
break token unless to_adapter.find_first({ column => token })
2010-07-18 23:32:56 +02:00
end
end
end
end
end
end