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/database_authenticatable.rb

127 lines
4.6 KiB
Ruby
Raw Normal View History

require 'devise/strategies/database_authenticatable'
2009-10-12 08:37:28 -03:00
module Devise
module Models
2009-10-09 09:27:44 -03:00
# Authenticable Module, responsible for encrypting password and validating
# authenticity of a user while signing in.
#
# Configuration:
2009-10-20 11:55:57 -02:00
#
# You can overwrite configuration values by setting in globally in Devise,
# using devise method or overwriting the respective instance method.
#
2009-10-09 09:27:44 -03:00
# pepper: encryption key used for creating encrypted password. Each time
# password changes, it's gonna be encrypted again, and this key
# is added to the password and salt to create a secure hash.
2009-10-20 11:55:57 -02:00
# Always use `rake secret' to generate a new key.
2009-10-15 15:52:25 -03:00
#
2009-10-09 09:27:44 -03:00
# stretches: defines how many times the password will be encrypted.
#
2009-11-15 03:31:13 -02:00
# encryptor: the encryptor going to be used. By default :sha1.
#
# authentication_keys: parameters used for authentication. By default [:email]
#
2009-10-09 09:27:44 -03:00
# Examples:
#
# User.authenticate('email@test.com', 'password123') # returns authenticated user or nil
# User.find(1).valid_password?('password123') # returns true/false
2009-10-20 11:55:57 -02:00
#
module DatabaseAuthenticatable
2010-02-17 12:35:38 +01:00
extend ActiveSupport::Concern
2010-02-17 12:35:38 +01:00
included do
attr_reader :password, :current_password
attr_accessor :password_confirmation
end
# Regenerates password salt and encrypted password each time password is set,
# and then trigger any "after_changed_password"-callbacks.
2009-10-15 15:52:25 -03:00
def password=(new_password)
@password = new_password
if @password.present?
self.password_salt = self.class.encryptor_class.salt
self.encrypted_password = password_digest(@password)
end
2009-10-15 15:52:25 -03:00
end
2009-12-15 01:20:59 +01:00
# Verifies whether an incoming_password (ie from sign in) is the user password.
def valid_password?(incoming_password)
password_digest(incoming_password) == self.encrypted_password
end
# Checks if a resource is valid upon authentication.
def valid_for_authentication?(attributes)
valid_password?(attributes[:password])
end
2010-02-08 23:14:03 +01:00
# Set password and password confirmation to nil
def clean_up_passwords
self.password = self.password_confirmation = nil
end
# Update record attributes when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects :password and
# :password_confirmation if they are blank.
def update_with_password(params={})
current_password = params.delete(:current_password)
2010-02-08 20:38:47 +01:00
params.delete(:password) if params[:password].blank?
2010-02-08 23:14:03 +01:00
params.delete(:password_confirmation) if params[:password_confirmation].blank?
result = if valid_password?(current_password)
update_attributes(params)
else
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
2010-02-08 23:14:03 +01:00
self.attributes = params
false
end
2010-02-08 23:14:03 +01:00
clean_up_passwords unless result
result
end
protected
# Digests the password using the configured encryptor.
def password_digest(password)
self.class.encryptor_class.digest(password, self.class.stretches, self.password_salt, self.class.pepper)
end
module ClassMethods
Devise::Models.config(self, :pepper, :stretches, :encryptor, :authentication_keys)
# Authenticate a user based on configured attribute keys. Returns the
2010-02-06 01:33:32 +01:00
# authenticated user if it's valid or nil.
def authenticate(attributes={})
2009-11-15 03:31:13 -02:00
return unless authentication_keys.all? { |k| attributes[k].present? }
conditions = attributes.slice(*authentication_keys)
resource = find_for_authentication(conditions)
resource if resource.try(:valid_for_authentication?, attributes)
end
# Returns the class for the configured encryptor.
def encryptor_class
@encryptor_class ||= ::Devise::Encryptors.const_get(encryptor.to_s.classify)
end
protected
# 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
# find(:first, :conditions => conditions)
# end
#
def find_for_authentication(conditions)
find(:first, :conditions => conditions)
end
end
2009-09-17 09:46:40 -03:00
end
end
end