I am a little confused about how to configure CanCanCan properly.
For starters, do I have to add load_and_authorize_resource
to every controller resource I want to restrict access to?
This is what I would like to do:
This is what my ability.rb
looks like:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
#Admin
if user.has_role? :admin
can :manage, :all
can :manage, :newsroom
# Editor
elsif user.has_role? :editor
can :read, :all
can :manage, :newsroom
can :manage, Post
#Member
elsif user.has_role? :member
can :read, :all
can :create, Post
can :status, Post
can :update, Post do |post|
post.try(:user) == user
end
#Guest
else
can :read, :all
can :create, Post
can :status, Post
end
end
end
In my routes.rb
I have this:
authenticate :user, lambda { |u| u.has_role? :admin or :editor } do
get 'newsroom', to: 'newsroom#index', as: "newsroom"
get 'newsroom/published', to: 'newsroom#published'
get 'newsroom/unpublished', to: 'newsroom#unpublished'
end
What is happening though, is when I am logged in with a user that has not been assigned any roles (i.e. what I want to be a "Guest"), they can access the Newsroom.
When I try to edit a post with the role of :member
, it gives me a "Not authorized to edit post" error (which is correct).
I just can't quite lockdown the Newsroom
and I am not sure why.
For what it's worth, I had to setup my NewsroomController
like this:
class NewsroomController < ApplicationController
authorize_resource :class => false
This is what the working version of my ability.rb
looks like after I got it to work with the permissions I needed:
#Roles
#Admin
if user.has_role? :admin
can :manage, :all
# Editor
elsif user.has_role? :editor
can :manage, :newsroom
can :manage, Post
#Member
elsif user.has_role? :member
can [:read, :create, :status], Post
can :update, Post do |post|
post.try(:user) == user
end
#Guest
else
can [:read, :status], Post
end