class ActiveAdmin::PunditAdapter

Public Instance Methods

authorized?(action, subject = nil) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 14
def authorized?(action, subject = nil)
  policy = retrieve_policy(subject)
  action = format_action(action, subject)

  policy.respond_to?(action) && policy.public_send(action)
end
format_action(action, subject) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 44
def format_action(action, subject)
  # https://github.com/varvet/pundit/blob/main/lib/generators/pundit/install/templates/application_policy.rb
  case action
  when Auth::READ then subject.is_a?(Class) ? :index? : :show?
  when Auth::DESTROY then subject.is_a?(Class) ? :destroy_all? : :destroy?
  else "#{action}?"
  end
end
retrieve_policy(subject) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 33
def retrieve_policy(subject)
  target = policy_target(subject)
  if (policy = policy(namespace(target)) || compat_policy(subject))
    policy
  elsif default_policy_class
    default_policy(subject)
  else
    raise Pundit::NotDefinedError, "unable to find a compatible policy for `#{target}`"
  end
end
scope_collection(collection, action = Auth::READ) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 21
def scope_collection(collection, action = Auth::READ)
  # scoping is appliable only to read/index action
  # which means there is no way how to scope other actions
  Pundit.policy_scope!(user, namespace(collection))
rescue Pundit::NotDefinedError => e
  if default_policy_class && default_policy_class.const_defined?(:Scope)
    default_policy_class::Scope.new(user, collection).resolve
  else
    raise e
  end
end

Private Instance Methods

compat_policy(subject) click to toggle source

This method is needed to fallback to our previous policy searching logic. I.e.: when class name contains ‘default_policy_namespace` (eg: ShopAdmin) we should try to search it without namespace. This is because that’s the only thing that worked in this case before we fixed our buggy namespace detection, so people are probably relying on it. This fallback might be removed in future versions of ActiveAdmin, so pundit_adapter search will work consistently with provided namespaces

# File lib/active_admin/pundit_adapter.rb, line 70
def compat_policy(subject)
  return unless default_policy_namespace

  target = policy_target(subject)

  return unless target.class.to_s.include?(default_policy_module) &&
    (policy = policy(target))

  policy_name = policy.class.to_s

  ActiveAdmin.deprecator.warn "You have `pundit_policy_namespace` configured as `#{default_policy_namespace}`, " \
    "but ActiveAdmin was unable to find policy #{default_policy_module}::#{policy_name}. " \
    "#{policy_name} will be used instead. " \
    "This behavior will be removed in future versions of ActiveAdmin. " \
    "To fix this warning, move your #{policy_name} policy to the #{default_policy_module} namespace"

  policy
end
default_policy(subject) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 101
def default_policy(subject)
  default_policy_class.new(user, subject)
end
default_policy_class() click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 97
def default_policy_class
  ActiveAdmin.application.pundit_default_policy && ActiveAdmin.application.pundit_default_policy.constantize
end
default_policy_module() click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 109
def default_policy_module
  default_policy_namespace.to_s.camelize
end
default_policy_namespace() click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 105
def default_policy_namespace
  ActiveAdmin.application.pundit_policy_namespace
end
namespace(object) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 89
def namespace(object)
  if default_policy_namespace && !object.class.to_s.start_with?("#{default_policy_module}::")
    [default_policy_namespace.to_sym, object]
  else
    object
  end
end
policies() click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 117
def policies
  @policies ||= {}
end
policy(target) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 113
def policy(target)
  policies[target] ||= Pundit.policy(user, target)
end
policy_target(subject) click to toggle source
# File lib/active_admin/pundit_adapter.rb, line 55
def policy_target(subject)
  case subject
  when nil then resource
  when Class then subject.new
  else subject
  end
end