Authorization

The default configuration of Administrate is "authenticate-only" - once a user is authenticated, that user has access to every action of every object.

You can add more fine-grained authorization by overriding methods in the controller.

Using Pundit

If your app already uses Pundit for authorization, you just need to add one line to your Admin::ApplicationController:

include Administrate::Punditize

This will use all the policies from your main app to determine if the current user is able to view a given record or perform a given action.

Further limiting scope

You may want to limit the scope for a given user beyond what they technically have access to see in the main app. For example, a user may have all public records in their scope, but you want to only show their records in the admin interface to reduce confusion.

In this case, you can add additional pundit policy_namespace in your controller and Administrate will use the namespaced pundit policy instead.

For example:

# app/controllers/admin/posts_controller.rb
module Admin
  class PostsController < ApplicationController
    include Administrate::Punditize

    def policy_namespace
      [:admin]
    end
  end
end

# app/policies/admin/post_policy.rb
module Admin
  class PostPolicy < ApplicationPolicy
    class Scope < Scope
      def resolve
        scope.where(owner: user)
      end
    end
  end
end

Authorization without Pundit

Pundit is not necessary to implement authorization within Administrate. It is simply a common solution that many in the community use, and for this reason Administrate provides a plugin to work with it. However you can use a different solution or roll out your own.

To integrate a different authorization solution, you will need to implement some methods in Admin::ApplicationController or its subclasses.

These are the methods to override, with examples:

# Used in listings, such as the `index` actions. It
# restricts the scope of records that a user can access.
# Returns an ActiveRecord scope.
def scoped_resource
  super.where(user: current_user)
end

# Return true if the current user can access the given
# resource, false otherwise.
def authorized_action?(resource, action)
  current_user.can?(resource, action)
end

Additionally, the method authorize_resource(resource) should throw an exception if the current user is not allowed to access the given resource. Normally you wouldn't need to override it, as the default implementation uses authorized_action? to produce the correct behaviour. However you may still want to override it if you want to raise a custom error type.