2010-03-29 16:13:19 +02:00
|
|
|
require 'devise/strategies/database_authenticatable'
|
2009-10-12 08:37:28 -03:00
|
|
|
|
2009-09-17 09:24:33 -03:00
|
|
|
module Devise
|
2009-10-09 08:30:25 -03:00
|
|
|
module Models
|
2016-02-10 17:00:49 -02:00
|
|
|
# Authenticatable Module, responsible for hashing the password and
|
|
|
|
# validating the authenticity of a user while signing in.
|
2009-10-09 09:27:44 -03:00
|
|
|
#
|
2010-07-15 13:01:31 +02:00
|
|
|
# == Options
|
2009-10-20 11:55:57 -02:00
|
|
|
#
|
2015-09-30 19:31:55 -03:00
|
|
|
# DatabaseAuthenticatable adds the following options to devise_for:
|
2009-10-20 11:55:57 -02:00
|
|
|
#
|
2011-08-05 17:07:54 +07:00
|
|
|
# * +pepper+: a random string used to provide a more secure hash. Use
|
|
|
|
# `rake secret` to generate new keys.
|
|
|
|
#
|
2010-09-25 16:08:46 +02:00
|
|
|
# * +stretches+: the cost given to bcrypt.
|
2009-11-15 03:31:13 -02:00
|
|
|
#
|
2010-07-15 13:01:31 +02:00
|
|
|
# == Examples
|
2009-10-09 09:27:44 -03:00
|
|
|
#
|
|
|
|
# User.find(1).valid_password?('password123') # returns true/false
|
2009-10-20 11:55:57 -02:00
|
|
|
#
|
2010-03-29 16:13:19 +02:00
|
|
|
module DatabaseAuthenticatable
|
2010-04-06 16:34:22 +02:00
|
|
|
extend ActiveSupport::Concern
|
2009-09-17 11:06:46 -03:00
|
|
|
|
2010-02-17 12:35:38 +01:00
|
|
|
included do
|
2015-06-19 14:22:37 -05:00
|
|
|
after_update :send_password_change_notification, if: :send_password_change_notification?
|
|
|
|
|
2010-02-17 12:35:38 +01:00
|
|
|
attr_reader :password, :current_password
|
|
|
|
attr_accessor :password_confirmation
|
2009-09-17 09:24:33 -03:00
|
|
|
end
|
|
|
|
|
2012-02-18 22:50:59 -02:00
|
|
|
def self.required_fields(klass)
|
|
|
|
[:encrypted_password] + klass.authentication_keys
|
2012-02-17 14:37:44 -02:00
|
|
|
end
|
|
|
|
|
2016-02-10 17:00:49 -02:00
|
|
|
# Generates a hashed password based on the given value.
|
|
|
|
# For legacy reasons, we use `encrypted_password` to store
|
|
|
|
# the hashed password.
|
2009-10-15 15:52:25 -03:00
|
|
|
def password=(new_password)
|
|
|
|
@password = new_password
|
2013-11-08 16:22:31 -02:00
|
|
|
self.encrypted_password = password_digest(@password) if @password.present?
|
2009-10-15 15:52:25 -03:00
|
|
|
end
|
|
|
|
|
2014-11-05 16:51:29 -05:00
|
|
|
# Verifies whether a password (ie from sign in) is the user password.
|
2010-09-28 17:45:06 +02:00
|
|
|
def valid_password?(password)
|
2014-03-25 09:44:40 -04:00
|
|
|
Devise::Encryptor.compare(self.class, encrypted_password, password)
|
2010-01-24 03:38:52 +01:00
|
|
|
end
|
|
|
|
|
2010-02-08 23:14:03 +01:00
|
|
|
# Set password and password confirmation to nil
|
|
|
|
def clean_up_passwords
|
2011-09-02 13:14:15 -04:00
|
|
|
self.password = self.password_confirmation = nil
|
2010-02-08 23:14:03 +01:00
|
|
|
end
|
|
|
|
|
2014-03-24 21:49:48 +01:00
|
|
|
# Update record attributes when :current_password matches, otherwise
|
|
|
|
# returns error on :current_password.
|
|
|
|
#
|
|
|
|
# This method also rejects the password field if it is blank (allowing
|
|
|
|
# users to change relevant information like the e-mail without changing
|
|
|
|
# their password). In case the password field is rejected, the confirmation
|
|
|
|
# is also rejected as long as it is also blank.
|
2011-11-24 12:51:03 +04:00
|
|
|
def update_with_password(params, *options)
|
2010-02-16 14:31:49 +01:00
|
|
|
current_password = params.delete(:current_password)
|
2010-02-08 20:38:47 +01:00
|
|
|
|
2010-04-25 09:38:56 +02:00
|
|
|
if params[:password].blank?
|
|
|
|
params.delete(:password)
|
|
|
|
params.delete(:password_confirmation) if params[:password_confirmation].blank?
|
|
|
|
end
|
2010-02-08 23:14:03 +01:00
|
|
|
|
2010-02-15 14:15:24 +01:00
|
|
|
result = if valid_password?(current_password)
|
2011-11-24 09:24:06 +00:00
|
|
|
update_attributes(params, *options)
|
2009-12-14 22:55:55 -02:00
|
|
|
else
|
2012-06-08 19:15:30 +02:00
|
|
|
self.assign_attributes(params, *options)
|
2011-06-21 17:23:07 -04:00
|
|
|
self.valid?
|
|
|
|
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
|
2009-12-14 22:55:55 -02:00
|
|
|
false
|
|
|
|
end
|
2010-02-08 23:14:03 +01:00
|
|
|
|
2010-04-01 14:00:21 +02:00
|
|
|
clean_up_passwords
|
2010-02-08 23:14:03 +01:00
|
|
|
result
|
2009-12-14 22:55:55 -02:00
|
|
|
end
|
|
|
|
|
2011-06-22 13:01:49 -03:00
|
|
|
# Updates record attributes without asking for the current password.
|
2012-11-29 17:15:15 +05:30
|
|
|
# Never allows a change to the current password. If you are using this
|
2011-10-25 18:37:53 +02:00
|
|
|
# method, you should probably override this method to protect other
|
|
|
|
# attributes you would not like to be updated without a password.
|
|
|
|
#
|
|
|
|
# Example:
|
|
|
|
#
|
2013-06-25 11:27:35 +02:00
|
|
|
# def update_without_password(params, *options)
|
2011-10-25 18:37:53 +02:00
|
|
|
# params.delete(:email)
|
|
|
|
# super(params)
|
|
|
|
# end
|
|
|
|
#
|
2011-11-24 12:51:03 +04:00
|
|
|
def update_without_password(params, *options)
|
2011-05-05 09:24:21 +02:00
|
|
|
params.delete(:password)
|
|
|
|
params.delete(:password_confirmation)
|
|
|
|
|
2011-11-24 09:24:06 +00:00
|
|
|
result = update_attributes(params, *options)
|
2011-05-05 09:24:21 +02:00
|
|
|
clean_up_passwords
|
|
|
|
result
|
|
|
|
end
|
2011-11-24 09:24:06 +00:00
|
|
|
|
2013-04-29 15:06:13 +02:00
|
|
|
# Destroy record when :current_password matches, otherwise returns
|
2013-10-24 08:15:53 +11:00
|
|
|
# error on :current_password. It also automatically rejects
|
2013-04-29 15:06:13 +02:00
|
|
|
# :current_password if it is blank.
|
|
|
|
def destroy_with_password(current_password)
|
|
|
|
result = if valid_password?(current_password)
|
|
|
|
destroy
|
|
|
|
else
|
|
|
|
self.valid?
|
|
|
|
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
result
|
|
|
|
end
|
|
|
|
|
2013-10-24 08:15:53 +11:00
|
|
|
# A callback initiated after successfully authenticating. This can be
|
|
|
|
# used to insert your own logic that is only run after the user successfully
|
|
|
|
# authenticates.
|
|
|
|
#
|
|
|
|
# Example:
|
|
|
|
#
|
|
|
|
# def after_database_authentication
|
|
|
|
# self.update_attribute(:invite_code, nil)
|
|
|
|
# end
|
|
|
|
#
|
2010-04-06 13:26:56 +02:00
|
|
|
def after_database_authentication
|
|
|
|
end
|
|
|
|
|
2010-09-25 16:08:46 +02:00
|
|
|
# A reliable way to expose the salt regardless of the implementation.
|
|
|
|
def authenticatable_salt
|
2012-03-10 11:10:57 +01:00
|
|
|
encrypted_password[0,29] if encrypted_password
|
2010-09-25 16:08:46 +02:00
|
|
|
end
|
|
|
|
|
2015-06-19 14:22:37 -05:00
|
|
|
def send_password_change_notification
|
|
|
|
send_devise_notification(:password_change)
|
|
|
|
end
|
|
|
|
|
2010-03-29 23:44:47 +02:00
|
|
|
protected
|
2009-11-18 09:26:47 -02:00
|
|
|
|
2016-02-10 17:00:49 -02:00
|
|
|
# Hashes the password using bcrypt. Custom hash functions should override
|
2013-11-08 16:22:31 -02:00
|
|
|
# this method to apply their own algorithm.
|
|
|
|
#
|
|
|
|
# See https://github.com/plataformatec/devise-encryptable for examples
|
2016-02-10 17:00:49 -02:00
|
|
|
# of other hashing engines.
|
2013-11-08 16:22:31 -02:00
|
|
|
def password_digest(password)
|
2014-03-25 09:44:40 -04:00
|
|
|
Devise::Encryptor.digest(self.class, password)
|
2013-11-08 16:22:31 -02:00
|
|
|
end
|
|
|
|
|
2015-06-19 14:22:37 -05:00
|
|
|
def send_password_change_notification?
|
|
|
|
self.class.send_password_change_notification && encrypted_password_changed?
|
|
|
|
end
|
|
|
|
|
2009-10-09 08:30:25 -03:00
|
|
|
module ClassMethods
|
2015-06-19 14:22:37 -05:00
|
|
|
Devise::Models.config(self, :pepper, :stretches, :send_password_change_notification)
|
2010-07-12 06:59:49 +02:00
|
|
|
|
2010-07-05 19:11:37 +02:00
|
|
|
# We assume this method already gets the sanitized values from the
|
|
|
|
# DatabaseAuthenticatable strategy. If you are using this method on
|
|
|
|
# your own, be sure to sanitize the conditions hash to only include
|
|
|
|
# the proper fields.
|
2010-04-06 13:26:56 +02:00
|
|
|
def find_for_database_authentication(conditions)
|
|
|
|
find_for_authentication(conditions)
|
2009-11-19 13:53:57 -02:00
|
|
|
end
|
2009-11-22 22:32:54 -02:00
|
|
|
end
|
2009-09-17 09:46:40 -03:00
|
|
|
end
|
2009-09-17 09:24:33 -03:00
|
|
|
end
|
|
|
|
end
|