class ActiveAdmin::PunditAdapter

def authorized?(action, subject = nil)

def authorized?(action, subject = nil)
  policy = retrieve_policy(subject)
  action = format_action(action, subject)
  policy.respond_to?(action) && policy.public_send(action)
end

def compat_policy(subject)

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

def default_policy(subject)

def default_policy(subject)
  default_policy_class.new(user, subject)
end

def default_policy_class

def default_policy_class
  ActiveAdmin.application.pundit_default_policy && ActiveAdmin.application.pundit_default_policy.constantize
end

def default_policy_module

def default_policy_module
  default_policy_namespace.to_s.camelize
end

def default_policy_namespace

def default_policy_namespace
  ActiveAdmin.application.pundit_policy_namespace
end

def format_action(action, subject)

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

def namespace(object)

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

def policies

def policies
  @policies ||= {}
end

def policy(target)

def policy(target)
  policies[target] ||= Pundit.policy(user, target)
end

def policy_target(subject)

def policy_target(subject)
  case subject
  when nil then resource
  when Class then subject.new
  else subject
  end
end

def retrieve_policy(subject)

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

def scope_collection(collection, action = Auth::READ)

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