-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
rememberable.rb
121 lines (106 loc) · 4.54 KB
/
rememberable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
require 'devise/strategies/rememberable'
require 'devise/hooks/rememberable'
require 'devise/hooks/forgetable'
module Devise
module Models
# 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.
#
# == Options
#
# Rememberable adds the following options in devise_for:
#
# * +remember_for+: the time you want the user will be remembered without
# asking for credentials. After this time the user will be blocked and
# will have to enter his credentials again. This configuration is also
# used to calculate the expires time for the cookie created to remember
# the user. By default remember_for is 2.weeks.
#
# * +extend_remember_period+: if true, extends the user's remember period
# when remembered via cookie. False by default.
#
# * +cookie_options+: configuration options passed to the created cookie.
#
# == Examples
#
# User.find(1).remember_me! # regenerating the token
# User.find(1).forget_me! # clearing the token
#
# # generating info to put into cookies
# User.serialize_into_cookie(user)
#
# # lookup the user based on the incoming cookie information
# User.serialize_from_cookie(cookie_string)
module Rememberable
extend ActiveSupport::Concern
attr_accessor :remember_me, :extend_remember_period
# 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.
def remember_me!(extend_period=false)
self.remember_token = self.class.remember_token if generate_remember_token?
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
save(:validate => false)
end
# If the record is persisted, remove the remember token (but only if
# it exists), and save the record without validations.
def forget_me!
return unless persisted?
self.remember_token = nil if respond_to?(:remember_token=)
self.remember_created_at = nil
save(:validate => false)
end
# Remember token should be expired if expiration time not overpass now.
def remember_expired?
remember_created_at.nil? || (remember_expires_at <= Time.now.utc)
end
# Remember token expires at created time + remember_for configuration
def remember_expires_at
remember_created_at + self.class.remember_for
end
def rememberable_value
if respond_to?(:remember_token)
remember_token
elsif salt = authenticatable_salt
salt
else
raise "authenticable_salt returned nil for the #{self.class.name} model. " \
"In order to use rememberable, you must ensure a password is always set " \
"or have a remember_token column in your model or implement your own " \
"rememberable_value in the model with custom logic."
end
end
def rememberable_options
self.class.rememberable_options
end
protected
def generate_remember_token?
respond_to?(:remember_token) && remember_expired?
end
# Generate a timestamp if extend_remember_period is true, if no remember_token
# exists, or if an existing remember token has expired.
def generate_remember_timestamp?(extend_period) #:nodoc:
extend_period || remember_created_at.nil? || remember_expired?
end
module ClassMethods
# Create the cookie key using the record id and remember_token
def serialize_into_cookie(record)
[record.to_key, record.rememberable_value]
end
# Recreate the user based on the stored cookie
def serialize_from_cookie(id, remember_token)
record = to_adapter.get(id)
record if record && record.rememberable_value == remember_token && !record.remember_expired?
end
# Generate a token checking if one does not already exist in the database.
def remember_token
generate_token(:remember_token)
end
Devise::Models.config(self, :remember_for, :extend_remember_period, :rememberable_options)
end
end
end
end