# frozen_string_literal: true module DeviseJwtAuth module Controllers module Helpers extend ActiveSupport::Concern module ClassMethods # Define authentication filters and accessor helpers for a group of mappings. # These methods are useful when you are working with multiple mappings that # share some functionality. They are pretty much the same as the ones # defined for normal mappings. # # Example: # # inside BlogsController (or any other controller, it doesn't matter which): # devise_group :blogger, contains: [:user, :admin] # # Generated methods: # authenticate_blogger! # Redirects unless user or admin are signed in # blogger_signed_in? # Checks whether there is either a user or an admin signed in # current_blogger # Currently signed in user or admin # current_bloggers # Currently signed in user and admin # render_authenticate_error # Render error unless user or admin are signed in # # Use: # before_action :authenticate_blogger! # Redirects unless either a user or an admin are authenticated # before_action ->{ authenticate_blogger! :admin } # Redirects to the admin login page # current_blogger :user # Preferably returns a User if one is signed in # def devise_jwt_auth_group(group_name, opts = {}) mappings = "[#{opts[:contains].map { |m| ":#{m}" }.join(',')}]" class_eval <<-METHODS, __FILE__, __LINE__ + 1 def authenticate_#{group_name}!(favourite=nil, opts={}) unless #{group_name}_signed_in? mappings = #{mappings} mappings.unshift mappings.delete(favourite.to_sym) if favourite mappings.each do |mapping| set_user_by_token(mapping) end unless current_#{group_name} render_authenticate_error end end end def #{group_name}_signed_in? #{mappings}.any? do |mapping| set_user_by_token(mapping) end end def current_#{group_name}(favourite=nil) mappings = #{mappings} mappings.unshift mappings.delete(favourite.to_sym) if favourite mappings.each do |mapping| current = set_user_by_token(mapping) return current if current end nil end def current_#{group_name.to_s.pluralize} #{mappings}.map do |mapping| set_user_by_token(mapping) end.compact end def render_authenticate_error return render json: { errors: [I18n.t('devise.failure.unauthenticated')] }, status: 401 end if respond_to?(:helper_method) helper_method( "current_#{group_name}", "current_#{group_name.to_s.pluralize}", "#{group_name}_signed_in?", "render_authenticate_error" ) end METHODS end def log_process_action(payload) payload[:status] ||= 401 unless payload[:exception] super end end # Define authentication filters and accessor helpers based on mappings. # These filters should be used inside the controllers as before_actions, # so you can control the scope of the user who should be signed in to # access that specific controller/action. # Example: # # Roles: # User # Admin # # Generated methods: # authenticate_user! # Signs user in or 401 # authenticate_admin! # Signs admin in or 401 # user_signed_in? # Checks whether there is a user signed in or not # admin_signed_in? # Checks whether there is an admin signed in or not # current_user # Current signed in user # current_admin # Current signed in admin # user_session # Session data available only to the user scope # admin_session # Session data available only to the admin scope # render_authenticate_error # Render error unless user or admin is signed in # # Use: # before_action :authenticate_user! # Tell devise to use :user map # before_action :authenticate_admin! # Tell devise to use :admin map # def self.define_helpers(mapping) #:nodoc: mapping = mapping.name class_eval <<-METHODS, __FILE__, __LINE__ + 1 def authenticate_#{mapping}!(opts={}) unless current_#{mapping} render_authenticate_error end end def #{mapping}_signed_in? !!current_#{mapping} end def current_#{mapping} @current_#{mapping} ||= set_user_by_token(:#{mapping}) end def #{mapping}_session current_#{mapping} && warden.session(:#{mapping}) end def render_authenticate_error return render json: { errors: [I18n.t('devise.failure.unauthenticated')] }, status: 401 end METHODS ActiveSupport.on_load(:action_controller) do if respond_to?(:helper_method) helper_method( "current_#{mapping}", "#{mapping}_signed_in?", "#{mapping}_session", 'render_authenticate_error' ) end end end end end end