mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Add extend_remember_period, closes #340.
This commit is contained in:
parent
5aeb8cf1cf
commit
058d433f28
6 changed files with 114 additions and 7 deletions
|
@ -97,6 +97,10 @@ module Devise
|
|||
mattr_accessor :remember_across_browsers
|
||||
@@remember_across_browsers = true
|
||||
|
||||
# Extend remember period everytime the user sign up.
|
||||
mattr_accessor :extend_remember_period
|
||||
@@extend_remember_period = false
|
||||
|
||||
# Time interval you can access your account before confirming your account.
|
||||
mattr_accessor :confirm_within
|
||||
@@confirm_within = 0.days
|
||||
|
|
|
@ -45,9 +45,8 @@ module Devise
|
|||
# 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!
|
||||
return if self.class.remember_across_browsers && self.remember_created_at && !self.remember_expired?
|
||||
self.remember_token = self.class.remember_token
|
||||
self.remember_created_at = Time.now.utc
|
||||
self.remember_token = self.class.remember_token if generate_remember_token?
|
||||
self.remember_created_at = Time.now.utc if generate_remember_timestamp?
|
||||
save(:validate => false)
|
||||
end
|
||||
|
||||
|
@ -63,7 +62,7 @@ module Devise
|
|||
|
||||
# Remember token should be expired if expiration time not overpass now.
|
||||
def remember_expired?
|
||||
remember_expires_at <= Time.now.utc
|
||||
remember_created_at && (remember_expires_at <= Time.now.utc)
|
||||
end
|
||||
|
||||
# Remember token expires at created time + remember_for configuration
|
||||
|
@ -79,6 +78,20 @@ module Devise
|
|||
self.class.cookie_domain != false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# We just don't generate a token if remember across browser is given,
|
||||
# a remember token exists or it was expired.
|
||||
def generate_remember_token? #:nodoc:
|
||||
!(self.class.remember_across_browsers && remember_token) || remember_expired?
|
||||
end
|
||||
|
||||
# We always generate a timestamp if extend_remember_period is true. Besides that,
|
||||
# we generate only if one does not exist or the current one expired.
|
||||
def generate_remember_timestamp? #:nodoc:
|
||||
self.class.extend_remember_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)
|
||||
|
@ -97,7 +110,8 @@ module Devise
|
|||
generate_token(:remember_token)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :remember_for, :remember_across_browsers, :cookie_domain)
|
||||
Devise::Models.config(self, :remember_for, :remember_across_browsers,
|
||||
:extend_remember_period, :cookie_domain)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'devise/strategies/base'
|
||||
require 'devise/hooks/rememberable'
|
||||
|
||||
module Devise
|
||||
module Strategies
|
||||
|
@ -7,6 +8,8 @@ module Devise
|
|||
# recreate the user from this cookie if it exists. Must be called *before*
|
||||
# authenticatable.
|
||||
class Rememberable < Devise::Strategies::Base
|
||||
include Devise::Hooks::Rememberable
|
||||
|
||||
# A valid strategy for rememberable needs a remember token in the cookies.
|
||||
def valid?
|
||||
remember_cookie.present?
|
||||
|
@ -28,6 +31,10 @@ module Devise
|
|||
|
||||
private
|
||||
|
||||
def remember_me?
|
||||
true
|
||||
end
|
||||
|
||||
def remember_key
|
||||
"remember_#{scope}_token"
|
||||
end
|
||||
|
|
|
@ -64,6 +64,9 @@ Devise.setup do |config|
|
|||
# If a valid remember token can be re-used between multiple browsers.
|
||||
# config.remember_across_browsers = true
|
||||
|
||||
# When true, extends remember period when user signs up via cookie.
|
||||
# config.extend_remember_period = true
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length
|
||||
# config.password_length = 6..20
|
||||
|
|
|
@ -3,7 +3,6 @@ require 'test_helper'
|
|||
class RememberMeTest < ActionController::IntegrationTest
|
||||
|
||||
def create_user_and_remember(add_to_token='')
|
||||
Devise.remember_for = 1
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
raw_cookie = User.serialize_into_cookie(user).tap { |a| a.last << add_to_token }
|
||||
|
@ -17,6 +16,16 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
request.cookie_jar['raw_cookie']
|
||||
end
|
||||
|
||||
def signed_cookie(key)
|
||||
controller.send(:cookies).signed[key]
|
||||
end
|
||||
|
||||
def cookie_expires(key)
|
||||
cookie = response.headers["Set-Cookie"].split("\n").grep(/^#{key}/).first
|
||||
cookie.split(";").map(&:strip).grep(/^expires=/)
|
||||
Time.parse($')
|
||||
end
|
||||
|
||||
test 'do not remember the user if he has not checked remember me option' do
|
||||
user = sign_in_as_user
|
||||
assert_nil request.cookies["remember_user_cookie"]
|
||||
|
@ -47,6 +56,34 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
assert warden.user(:user) == user
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are true, sends the same token with a new expire date' do
|
||||
swap Devise, :remember_across_browsers => true, :extend_remember_period => true, :remember_for => 1.year do
|
||||
user = create_user_and_remember
|
||||
token = user.remember_token
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save!
|
||||
|
||||
get users_path
|
||||
assert (cookie_expires("remember_user_token") - 1.year) > (old + 5.minutes)
|
||||
assert_equal token, signed_cookie("remember_user_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are false, sends a new token with old expire date' do
|
||||
swap Devise, :remember_across_browsers => false, :extend_remember_period => false, :remember_for => 1.year do
|
||||
user = create_user_and_remember
|
||||
token = user.remember_token
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save!
|
||||
|
||||
get users_path
|
||||
assert (cookie_expires("remember_user_token") - 1.year) < (old + 5.minutes)
|
||||
assert_not_equal token, signed_cookie("remember_user_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'do not remember other scopes' do
|
||||
user = create_user_and_remember
|
||||
get root_path
|
||||
|
|
|
@ -108,8 +108,50 @@ class RememberableTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is false, remember_me! should generate a new timestamp if expired' do
|
||||
swap Devise, :extend_remember_period => false, :remember_for => 5.minutes do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save
|
||||
|
||||
user.remember_me!
|
||||
assert_not_equal old, user.remember_created_at
|
||||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is false, remember_me! should not generate a new timestamp' do
|
||||
swap Devise, :extend_remember_period => false, :remember_for => 1.year do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save
|
||||
|
||||
user.remember_me!
|
||||
assert_equal old, user.remember_created_at
|
||||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is true, remember_me! should always generate a new timestamp' do
|
||||
swap Devise, :extend_remember_period => true, :remember_for => 1.year do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save
|
||||
|
||||
user.remember_me!
|
||||
assert_not_equal old, user.remember_created_at
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should create a new token if no token exists' do
|
||||
swap Devise, :remember_across_browsers => true do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 1.year do
|
||||
user = create_user
|
||||
assert_equal nil, user.remember_token
|
||||
user.remember_me!
|
||||
|
|
Loading…
Reference in a new issue