Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/generators/sorcery/templates/initializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
#
# config.cookie_domain =

# Set name of the remember_me cookie
# Default: `:remember_me_token`
#
# config.remember_me_cookie_name =

# Allow the remember_me cookie to be set through AJAX
# Default: `true`
#
Expand Down
13 changes: 8 additions & 5 deletions lib/sorcery/controller/submodules/remember_me.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ def self.included(base)
base.send(:include, InstanceMethods)
Config.module_eval do
class << self
attr_accessor :remember_me_cookie_name
attr_accessor :remember_me_httponly

def merge_remember_me_defaults!
@defaults.merge!(:@remember_me_httponly => true)
@defaults.merge!(:@remember_me_cookie_name => :remember_me_token,
:@remember_me_httponly => true)
end
end
merge_remember_me_defaults!
Expand All @@ -36,13 +39,13 @@ def remember_me!
# Clears the cookie, and depending on the value of remember_me_token_persist_globally, may clear the token value.
def forget_me!
current_user.forget_me!
cookies.delete(:remember_me_token, domain: Config.cookie_domain)
cookies.delete(Config.remember_me_cookie_name.to_sym, domain: Config.cookie_domain)
end

# Clears the cookie, and clears the token value.
def force_forget_me!
current_user.force_forget_me!
cookies.delete(:remember_me_token, domain: Config.cookie_domain)
cookies.delete(Config.remember_me_cookie_name.to_sym, domain: Config.cookie_domain)
end

# Override.
Expand All @@ -59,7 +62,7 @@ def auto_login(user, should_remember = false)
# and logs the user in if found.
# Runs as a login source. See 'current_user' method for how it is used.
def login_from_cookie
user = cookies.signed[:remember_me_token] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[:remember_me_token]) if defined? cookies
user = cookies.signed[Config.remember_me_cookie_name.to_sym] && user_class.sorcery_adapter.find_by_remember_me_token(cookies.signed[Config.remember_me_cookie_name.to_sym]) if defined? cookies
if user && user.has_remember_me_token?
set_remember_me_cookie!(user)
session[:user_id] = user.id.to_s
Expand All @@ -71,7 +74,7 @@ def login_from_cookie
end

def set_remember_me_cookie!(user)
cookies.signed[:remember_me_token] = {
cookies.signed[Config.remember_me_cookie_name.to_sym] = {
value: user.send(user.sorcery_config.remember_me_token_attribute_name),
expires: user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name),
httponly: Config.remember_me_httponly,
Expand Down
72 changes: 72 additions & 0 deletions spec/controllers/controller_remember_me_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@
expect(cookies.signed['remember_me_token']).to eq assigns[:current_user].remember_me_token
end

it 'sets cookie on remember_me! with custom cookie name' do
sorcery_controller_property_set(:remember_me_cookie_name, :custom)

expect(User).to receive(:authenticate).with('[email protected]', 'secret') { |&block| block.call(user, nil) }
expect(user).to receive(:remember_me!)

post :test_login_with_remember, params: { email: '[email protected]', password: 'secret' }

expect(cookies.signed['custom']).to eq assigns[:current_user].remember_me_token

# Reset property back to default so it won't interfere with other tests.
sorcery_controller_property_set(:remember_me_cookie_name, :remember_me_token)
end

it 'clears cookie on forget_me!' do
cookies['remember_me_token'] = { value: 'asd54234dsfsd43534', expires: 3600 }
get :test_logout
Expand Down Expand Up @@ -58,6 +72,22 @@
expect(cookies.signed['remember_me_token']).to eq assigns[:user].remember_me_token
end

it 'login(email,password,remember_me) logs user in and remembers with custom cookie name' do
sorcery_controller_property_set(:remember_me_cookie_name, :custom)

expect(User).to receive(:authenticate).with('[email protected]', 'secret', '1') { |&block| block.call(user, nil) }
expect(user).to receive(:remember_me!)
expect(user).to receive(:remember_me_token).and_return('abracadabra').twice
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this receive the token twice? I'm not very familiar with the callback system, but this looks like it might be a side-effect of the double callback bug in 0.13.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@athix to be honest, I copied it over from the testcase above this one. So it could be part of the double callback bug. When I remove the twice method though, it gives an error. Could it be that the double callback bug is still relevant?


post :test_login_with_remember_in_login, params: { email: '[email protected]', password: 'secret', remember: '1' }

expect(cookies.signed['custom']).not_to be_nil
expect(cookies.signed['custom']).to eq assigns[:user].remember_me_token

# Reset property back to default so it won't interfere with other tests.
sorcery_controller_property_set(:remember_me_cookie_name, :remember_me_token)
end

it 'logout also calls forget_me!' do
session[:user_id] = user.id.to_s
expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user)
Expand All @@ -68,6 +98,21 @@
expect(cookies['remember_me_token']).to be_nil
end

it 'logout also calls forget_me! with custom cookie name' do
sorcery_controller_property_set(:remember_me_cookie_name, 'custom')

session[:user_id] = user.id.to_s
expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user)
expect(user).to receive(:remember_me!)
expect(user).to receive(:forget_me!)
get :test_logout_with_remember

expect(cookies['custom']).to be_nil

# Reset property back to default so it won't interfere with other tests.
sorcery_controller_property_set(:remember_me_cookie_name, :remember_me_token)
end

it 'logs user in from cookie' do
session[:user_id] = user.id.to_s
expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user)
Expand All @@ -90,6 +135,33 @@
expect(assigns[:current_user]).to eq user
end

it 'logs user in from cookie with custom cookie name' do
sorcery_controller_property_set(:remember_me_cookie_name, :custom)

session[:user_id] = user.id.to_s
expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user)
expect(user).to receive(:remember_me!)
expect(user).to receive(:remember_me_token).and_return('token')
expect(user).to receive(:has_remember_me_token?) { true }

subject.remember_me!
subject.instance_eval do
remove_instance_variable :@current_user
end
session[:user_id] = nil

expect(User.sorcery_adapter).to receive(:find_by_remember_me_token).with('token').and_return(user)

expect(subject).to receive(:after_remember_me!).with(user)

get :test_login_from_cookie

expect(assigns[:current_user]).to eq user

# Reset property back to default so it won't interfere with other tests.
sorcery_controller_property_set(:remember_me_cookie_name, :remember_me_token)
end

it 'doest not remember_me! when not asked to, even if third parameter is used' do
post :test_login_with_remember_in_login, params: { email: '[email protected]', password: 'secret', remember: '0' }

Expand Down