- General Configuration
- Site Title Options
- Internationalization (I18n)
- Load paths
- Utility Navigation
- Working with Resources
- Rename the Resource
- Customize the Namespace
- Customize the Menu
- Scoping the queries
- Customizing resource retrieval
- Belongs To
- Customizing the Index Page
- Customizing the CSV format
- Customizing the Form
- Customize the Show Page
- Sidebar Sections
- Custom Controller Actions
- Index Batch Actions
- Custom Pages
- Arbre Components
- Authorization Adapter
Active Admin offers the ability to define and use your own authorization adapter. If implemented, the '#authorized?' will be called when an action is taken. By default, '#authorized?' returns true.
Setting up your own AuthorizationAdapter
Setting up your own
AuthorizationAdapter is easy! The following example shows
how to set up and tie your authorization adapter class to Active Admin:
# app/models/only_authors_authorization.rb class OnlyAuthorsAuthorization < ActiveAdmin::AuthorizationAdapter def authorized?(action, subject = nil) case subject when normalized(Post) # Only let the author update and delete posts if action == :update || action == :destroy subject.author == user else true end else true end end end
In order to hook up
OnlyAuthorsAuthorization to Active Admin, go to your
config/initializers/active_admin.rb and add/modify the line:
config.authorization_adapter = "OnlyAuthorsAuthorization"
Authorization adapters can be configured per ActiveAdmin namespace as well, for example:
ActiveAdmin.setup do |config| config.namespace :admin do |ns| ns.authorization_adapter = "AdminAuthorization" end config.namespace :my do |ns| ns.authorization_adapter = "DashboardAuthorization" end end
Now, whenever a controller action is performed, the
#authorized? method will be called.
Getting Access to the Current User
From within your authorization adapter, you can call the
#user method to
retrieve the current user.
class OnlyAdmins < ActiveAdmin::AuthorizationAdapter def authorized?(action, subject = nil) user.admin? end end
Scoping Collections in Authorization Adapters
ActiveAdmin::AuthorizationAdapter also provides a hook method (
for the adapter to scope the resource's collection. For example, you may want to
centralize the scoping:
class OnlyMyAccount < ActiveAdmin::AuthorizationAdapter def authorized?(action, subject = nil) subject.account == user.account end def scope_collection(collection, action = Auth::READ) collection.where(:account_id => user.account_id) end end
All collections presented on Index Screens will be passed through this method and will be scoped accordingly.
Managing Access to Pages
Pages, just like resources, get authorized also. When authorization a page, the
subject will be an instance of
class OnlyDashboard < ActiveAdmin::AuthorizationAdapter def authorized?(action, subject = nil) case subject when ActiveAdmin::Page action == :read && subject.name == "Dashboard" else false end end end
By default Active Admin simplifies the controller actions into 4 actions:
:read- This controls if the user can view the menu item as well as the index and show screens.
:create- This controls if the user can view the new screen and submit the form to the create action.
:update- This controls if the user can view the edit screen and submit the form to the update action.
:destroy- This controls if the user can delete a resource.
Each of these actions is available as a constant. Eg:
:read is available as
Checking for Authorization in Controllers and Views
Active Admin provides a helper method to check if the current user is authorized to perform an action on a subject.
Simply use the `#authorized?(action, subject) method to check.
ActiveAdmin.register Post do index do column :title column '' do |post| link_to 'Edit', admin_post_path(post) if authorized? :update, post end end end
If you are implementing a custom controller action, you can use the
#authorize! method to raise an
ActiveAdmin.register Post do member_action :publish, method: :post do post = Post.find(params[:id]) authorize! :publish, post post.publish! flash[:notice] = "Post has been published" redirect_to [:admin, post] end action_item :publish, :only => :show do if !post.published? && authorized?(:publish, post) link_to "Publish", publish_admin_post_path(post), method: :post end end end
Using the CanCan Adapter
ActiveAdmin::AuthorizationAdapter is fairly low level. Many times
it's nicer to have a simpler DSL for managing authorization. Active Admin
provides an adapter out of the box for CanCan
To use the CanCan adapter, simply update the configuration in the Active Admin initializer:
config.authorization_adapter = ActiveAdmin::CanCanAdapter
You can also specify a method to be called on unauthorized access. This is necessary in order to prevent a redirect loop that can happen if a user tries to access a page they don't have permissions for (see #2081).
config.on_unauthorized_access = :access_denied
access_denied would be defined in
application_controller.rb. Here is one
example that redirects the user from the page they don't have permission to
access to a resource they have permission to access (organizations in this case), and
also displays the error message in the browser:
class ApplicationController < ActionController::Base protect_from_forgery def access_denied(exception) redirect_to admin_organizations_path, :alert => exception.message end end
By default this will use the ability class named "Ability". This can also be changed from the initializer:
config.cancan_ability_class = "MyCustomAbility"
Now you can simply use CanCan or CanCanCan the way that you would expect and Active Admin will use it for authorization:
# app/models/ability.rb class Ability include CanCan::Ability def initialize(user) can :manage, Post can :read, User can :manage, User, :id => user.id can :read, ActiveAdmin::Page, :name => "Dashboard" end end
Using the Pundit Adapter
Active Admin provides an adapter out of the box also for Pundit.
To use the Pundit adapter, simply update the configuration in the Active Admin initializer:
config.authorization_adapter = ActiveAdmin::PunditAdapter
You can simply use Pundit the way that you would expect and Active Admin will use it for authorization. Check Pundit's documentation to set up Pundit in your application. If you want to use batch actions just ensure that
destroy_all? method is defined in your policy class. You can use this template policy in your application instead of default one generated by Pundit's
rails g pundit:install command.