120 lines
4.7 KiB
Ruby
120 lines
4.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Devise
|
|
module Controllers
|
|
# Provide sign in and sign out functionality.
|
|
# Included by default in all controllers.
|
|
module SignInOut
|
|
# Return true if the given scope is signed in session. If no scope given, return
|
|
# true if any scope is signed in. This will run authentication hooks, which may
|
|
# cause exceptions to be thrown from this method; if you simply want to check
|
|
# if a scope has already previously been authenticated without running
|
|
# authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
|
|
def signed_in?(scope=nil)
|
|
[scope || Devise.mappings.keys].flatten.any? do |_scope|
|
|
warden.authenticate?(scope: _scope)
|
|
end
|
|
end
|
|
|
|
# Sign in a user that already was authenticated. This helper is useful for logging
|
|
# users in after sign up. All options given to sign_in is passed forward
|
|
# to the set_user method in warden.
|
|
# If you are using a custom warden strategy and the timeoutable module, you have to
|
|
# set `env["devise.skip_timeout"] = true` in the request to use this method, like we do
|
|
# in the sessions controller: https://github.com/heartcombo/devise/blob/master/app/controllers/devise/sessions_controller.rb#L7
|
|
#
|
|
# Examples:
|
|
#
|
|
# sign_in :user, @user # sign_in(scope, resource)
|
|
# sign_in @user # sign_in(resource)
|
|
# sign_in @user, event: :authentication # sign_in(resource, options)
|
|
# sign_in @user, store: false # sign_in(resource, options)
|
|
#
|
|
def sign_in(resource_or_scope, *args)
|
|
options = args.extract_options!
|
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
resource = args.last || resource_or_scope
|
|
|
|
expire_data_after_sign_in!
|
|
|
|
if options[:bypass]
|
|
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
|
[Devise] bypass option is deprecated and it will be removed in future version of Devise.
|
|
Please use bypass_sign_in method instead.
|
|
Example:
|
|
|
|
bypass_sign_in(user)
|
|
DEPRECATION
|
|
warden.session_serializer.store(resource, scope)
|
|
elsif warden.user(scope) == resource && !options.delete(:force)
|
|
# Do nothing. User already signed in and we are not forcing it.
|
|
true
|
|
else
|
|
warden.set_user(resource, options.merge!(scope: scope))
|
|
end
|
|
end
|
|
|
|
# Sign in a user bypassing the warden callbacks and stores the user
|
|
# straight in session. This option is useful in cases the user is already
|
|
# signed in, but we want to refresh the credentials in session.
|
|
#
|
|
# Examples:
|
|
#
|
|
# bypass_sign_in @user, scope: :user
|
|
# bypass_sign_in @user
|
|
def bypass_sign_in(resource, scope: nil)
|
|
scope ||= Devise::Mapping.find_scope!(resource)
|
|
expire_data_after_sign_in!
|
|
warden.session_serializer.store(resource, scope)
|
|
end
|
|
|
|
# Sign out a given user or scope. This helper is useful for signing out a user
|
|
# after deleting accounts. Returns true if there was a logout and false if there
|
|
# is no user logged in on the referred scope
|
|
#
|
|
# Examples:
|
|
#
|
|
# sign_out :user # sign_out(scope)
|
|
# sign_out @user # sign_out(resource)
|
|
#
|
|
def sign_out(resource_or_scope=nil)
|
|
return sign_out_all_scopes unless resource_or_scope
|
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
user = warden.user(scope: scope, run_callbacks: false) # If there is no user
|
|
|
|
warden.logout(scope)
|
|
warden.clear_strategies_cache!(scope: scope)
|
|
instance_variable_set(:"@current_#{scope}", nil)
|
|
|
|
!!user
|
|
end
|
|
|
|
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
|
# in one click. This signs out ALL scopes in warden. Returns true if there was at least one logout
|
|
# and false if there was no user logged in on all scopes.
|
|
def sign_out_all_scopes(lock=true)
|
|
users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
|
|
|
|
warden.logout
|
|
expire_data_after_sign_out!
|
|
warden.clear_strategies_cache!
|
|
warden.lock! if lock
|
|
|
|
users.any?
|
|
end
|
|
|
|
private
|
|
|
|
def expire_data_after_sign_in!
|
|
# session.keys will return an empty array if the session is not yet loaded.
|
|
# This is a bug in both Rack and Rails.
|
|
# A call to #empty? forces the session to be loaded.
|
|
session.empty?
|
|
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
|
end
|
|
|
|
alias :expire_data_after_sign_out! :expire_data_after_sign_in!
|
|
end
|
|
end
|
|
end
|