Search code examples
ruby-on-railsrubyauthorizationcancan

How to authorise action in a controller using CanCan ability?


I'm using CanCan gem for authorisation in my Rails project.

The ability.rb file look something like:

class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user || User.new
    send @user.role.name.underscore unless @user.role.nil?
  end

  private

  def partneradmin
    can :manage,  :all
    cannot :access, User, role_id: @user.role.id
    cannot :manage, Watchlist
    can :manage, Attachment
  end

end

I have another controller controllers/admin/users_controller.rb which looks like:

class Admin::UsersController < AdminController

  load_and_authorize_resource

  respond_to :html, :json

  def index
  end

  def new
  end
end

Now I want to restrict access to Admin::UsersController#index action so partneradmin user can't access the action. I tried to add cannot :access, Admin::UsersController but with no luck as I can still access Admin::UsersController#index page.

Please note that I don't want to restrict access for all Users resources. As for example I have PartnerAdmin::UsersController#index and I don't want to restrict it but only for Admin::UsersController#index (based on the controller and not model).


Solution

  • I had to add cannot :index, AdminController so ability.rb would look:

      def partneradmin
         can :manage,  :all
         cannot :access, User, role_id: @user.role.id
         cannot :manage, Watchlist
         can :manage, Attachment 
         cannot :index, AdminController
       end
    

    Then to add authorize_resource :class => AdminController in the controller.