2010-01-14 09:47:14 -05:00
|
|
|
require 'devise/strategies/rememberable'
|
|
|
|
require 'devise/hooks/rememberable'
|
2010-04-06 10:34:22 -04:00
|
|
|
require 'devise/hooks/forgetable'
|
2010-01-14 09:47:14 -05:00
|
|
|
|
2009-10-19 22:31:33 -04:00
|
|
|
module Devise
|
|
|
|
module Models
|
2009-10-19 22:52:31 -04:00
|
|
|
# Rememberable manages generating and clearing token for remember the user
|
|
|
|
# from a saved cookie. Rememberable also has utility methods for dealing
|
|
|
|
# with serializing the user into the cookie and back from the cookie, trying
|
|
|
|
# to lookup the record based on the saved information.
|
|
|
|
# You probably wouldn't use rememberable methods directly, they are used
|
|
|
|
# mostly internally for handling the remember token.
|
2009-10-22 07:49:19 -04:00
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# == Options
|
2009-10-22 07:49:19 -04:00
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# Rememberable adds the following options in devise_for:
|
2009-10-22 07:49:19 -04:00
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# * +remember_for+: the time you want the user will be remembered without
|
|
|
|
# asking for credentials. After this time the user will be blocked and
|
2010-09-25 15:13:54 -04:00
|
|
|
# will have to enter his credentials again. This configuration is also
|
2010-07-15 07:01:31 -04:00
|
|
|
# used to calculate the expires time for the cookie created to remember
|
|
|
|
# the user. By default remember_for is 2.weeks.
|
2010-07-23 12:31:39 -04:00
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# * +remember_across_browsers+: if a valid remember token can be re-used
|
2010-09-25 06:37:06 -04:00
|
|
|
# between multiple browsers. By default remember_across_browsers is true
|
|
|
|
# and cannot be turned off if you are using password salt instead of remember
|
|
|
|
# token.
|
2010-06-29 21:54:19 -04:00
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# * +extend_remember_period+: if true, extends the user's remember period
|
|
|
|
# when remembered via cookie. False by default.
|
|
|
|
#
|
2010-09-25 15:13:54 -04:00
|
|
|
# * +cookie_options+: configuration options passed to the created cookie.
|
|
|
|
#
|
2010-07-15 07:01:31 -04:00
|
|
|
# == Examples
|
2009-10-19 22:52:31 -04:00
|
|
|
#
|
|
|
|
# User.find(1).remember_me! # regenerating the token
|
|
|
|
# User.find(1).forget_me! # clearing the token
|
2009-10-20 06:44:21 -04:00
|
|
|
#
|
2009-10-19 22:52:31 -04:00
|
|
|
# # generating info to put into cookies
|
|
|
|
# User.serialize_into_cookie(user)
|
2009-10-20 06:44:21 -04:00
|
|
|
#
|
2009-10-19 22:52:31 -04:00
|
|
|
# # lookup the user based on the incoming cookie information
|
|
|
|
# User.serialize_from_cookie(cookie_string)
|
2009-10-19 22:31:33 -04:00
|
|
|
module Rememberable
|
2010-02-17 06:35:38 -05:00
|
|
|
extend ActiveSupport::Concern
|
2009-10-19 22:31:33 -04:00
|
|
|
|
2011-02-24 15:55:41 -05:00
|
|
|
attr_accessor :remember_me, :extend_remember_period
|
2009-10-19 22:31:33 -04:00
|
|
|
|
2010-06-29 21:54:19 -04:00
|
|
|
# Generate a new remember token and save the record without validations
|
|
|
|
# unless remember_across_browsers is true and the user already has a valid token.
|
2010-07-23 17:57:31 -04:00
|
|
|
def remember_me!(extend_period=false)
|
2010-09-25 06:37:06 -04:00
|
|
|
self.remember_token = self.class.remember_token if respond_to?(:remember_token) && generate_remember_token?
|
2010-07-23 17:57:31 -04:00
|
|
|
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
|
2010-02-16 08:31:49 -05:00
|
|
|
save(:validate => false)
|
2009-10-19 22:31:33 -04:00
|
|
|
end
|
|
|
|
|
2011-04-23 09:58:26 -04:00
|
|
|
# If the record is persisted, remove the remember token (but only if
|
|
|
|
# it exists), and save the record without validations.
|
2009-10-19 22:31:33 -04:00
|
|
|
def forget_me!
|
2011-04-23 09:58:26 -04:00
|
|
|
if persisted?
|
2011-04-22 20:56:54 -04:00
|
|
|
self.remember_token = nil if respond_to?(:remember_token=)
|
|
|
|
self.remember_created_at = nil
|
|
|
|
save(:validate => false)
|
|
|
|
end
|
2009-10-19 22:31:33 -04:00
|
|
|
end
|
|
|
|
|
2009-10-22 07:09:34 -04:00
|
|
|
# Remember token should be expired if expiration time not overpass now.
|
|
|
|
def remember_expired?
|
2010-09-25 06:37:06 -04:00
|
|
|
remember_created_at.nil? || (remember_expires_at <= Time.now.utc)
|
2009-10-22 07:09:34 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Remember token expires at created time + remember_for configuration
|
|
|
|
def remember_expires_at
|
2009-11-22 19:32:54 -05:00
|
|
|
remember_created_at + self.class.remember_for
|
2009-10-19 22:31:33 -04:00
|
|
|
end
|
2010-01-14 07:38:02 -05:00
|
|
|
|
2010-09-25 06:37:06 -04:00
|
|
|
def rememberable_value
|
2010-11-11 16:51:19 -05:00
|
|
|
if respond_to?(:remember_token)
|
|
|
|
remember_token
|
|
|
|
elsif respond_to?(:authenticatable_salt) && (salt = authenticatable_salt)
|
|
|
|
salt
|
|
|
|
else
|
|
|
|
raise "The #{self.class.name} class does not respond to remember_token and " <<
|
|
|
|
"authenticatable_salt returns nil. In order to use rememberable, you must " <<
|
|
|
|
"add a remember_token field to your model or ensure a password is always set."
|
|
|
|
end
|
2010-09-25 06:37:06 -04:00
|
|
|
end
|
|
|
|
|
2010-09-25 15:13:54 -04:00
|
|
|
def cookie_options
|
|
|
|
self.class.cookie_options
|
|
|
|
end
|
|
|
|
|
2010-07-23 10:31:42 -04:00
|
|
|
protected
|
|
|
|
|
2010-07-23 12:31:39 -04:00
|
|
|
# Generate a token unless remember_across_browsers is true and there is
|
|
|
|
# an existing remember_token or the existing remember_token has expried.
|
2010-07-23 10:31:42 -04:00
|
|
|
def generate_remember_token? #:nodoc:
|
|
|
|
!(self.class.remember_across_browsers && remember_token) || remember_expired?
|
|
|
|
end
|
|
|
|
|
2010-07-23 12:31:39 -04:00
|
|
|
# Generate a timestamp if extend_remember_period is true, if no remember_token
|
|
|
|
# exists, or if an existing remember token has expired.
|
2010-07-23 17:57:31 -04:00
|
|
|
def generate_remember_timestamp?(extend_period) #:nodoc:
|
|
|
|
extend_period || remember_created_at.nil? || remember_expired?
|
2010-07-23 10:31:42 -04:00
|
|
|
end
|
|
|
|
|
2010-01-14 07:38:02 -05:00
|
|
|
module ClassMethods
|
|
|
|
# Create the cookie key using the record id and remember_token
|
|
|
|
def serialize_into_cookie(record)
|
2010-10-03 13:37:40 -04:00
|
|
|
[record.to_key, record.rememberable_value]
|
2010-01-14 07:38:02 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Recreate the user based on the stored cookie
|
2010-03-31 07:31:45 -04:00
|
|
|
def serialize_from_cookie(id, remember_token)
|
2010-10-10 11:51:12 -04:00
|
|
|
record = to_adapter.get(id)
|
2010-09-25 06:37:06 -04:00
|
|
|
record if record && record.rememberable_value == remember_token && !record.remember_expired?
|
2010-01-14 07:38:02 -05:00
|
|
|
end
|
|
|
|
|
2010-07-18 17:32:56 -04:00
|
|
|
# Generate a token checking if one does not already exist in the database.
|
|
|
|
def remember_token
|
|
|
|
generate_token(:remember_token)
|
|
|
|
end
|
|
|
|
|
2010-07-23 10:31:42 -04:00
|
|
|
Devise::Models.config(self, :remember_for, :remember_across_browsers,
|
2010-09-25 15:13:54 -04:00
|
|
|
:extend_remember_period, :cookie_options)
|
2010-01-14 07:38:02 -05:00
|
|
|
end
|
2009-10-19 22:31:33 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|