Using cancan to prevent access to controller
I have an admin controller and I want that only users that are defined as admin would have access to that controller.
my ability class:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
end
end
end
my admin controller:
class 开发者_如何学运维AdminController < ApplicationController
load_and_authorize_resource
def index
end
def users_list
end
end
when i try to access /admin/users_list
(either with an admin user or without) i get the following error: uninitialized constant Admin
What am I doing wrong? Is that the right way to restrict access to a controller?
This is because when you are using load_and_authorize_resource your controller must be backed by a model named Admin (since your controller is called AdminController). Thus you need to either create this model or replace load_and_authorize_resource with:
authorize_resource :class => false
which causes the access checks to be made against your actions rather than the model. Note this unfortunately causes the generic access symbols such as :manage and :read to stop working requiring you to refernce the controller actions directly in ability.rb:
can [ :index, :users_list ], :admin
where the first argument is a array of controller actions the user can access and the second argument is the short name of the controller
You can put authorization in your controller
authorize_resource :class => false
or
authorize_resource :class => :controller
Then change your app/models/Ability.rb file
can :manage, :controller_name
See this
Check this to add authorization rules for non-restful-controllers:
https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
Hope this helps.
This is because when you make a generic controller, put load_and_authorize_resource then the application controller or admin controller could not find the actual class which it come from like this example. This will work.
class Admin::HomeController < Admin::ApplicationController
def home
end
end
class Admin::ApplicationController < ApplicationController
load_and_authorize_resource :class => self.class
end
I had the same issue. My solution was define a cannot ability. Insted of define what only the Admin can do, I'm defining what the no admin user can not do. In your code would be something like this:
Admin controller:
class AdminController < ApplicationController
authorize_resource :class => AdminController
def index
end
def users_list
end
end
ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
if user.admin?
can :manage, :all
else
can :read, :all
cannot [:index, :users_list], AdminController
end
end
end
精彩评论