I successfully made login system with Devise and CanCan, and I have 3 types of users. Admin, internal and global users. I created Controllers and index actions: Admin, Cpanel, Report and State, and I want to restrict access to this controllers for some users.
Admin user should have privilegies to access: Reports(all), State (read), Admin (all)
Global user should have privilegies to access: Reports(only read), State(read), Cpanel(all)
Internal user should have privilegies to access: Reports(all), State (read)
And I tried to do this with following code in ability.rs:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role? :admin
can :manage, [Report, Admin]
can :read, State
elsif user.role? :global_user
can :read, [Report, State]
can :manage, Cpanel
elsif user.role? :internal_user
can :manage, Report
can :read, State
end
end
end
At this time I have only index actions in this controllers, and when I login to app with internal user I CAN access to /admin for example, and that is not behavior that I want. I want to restrict access to all controllers instead of controllers listed in ability.rb class.
Source code is here
If I were going to prevent access to an entire controller, I would make a before filter that redirects the user to an access denied page if he does not have the admin role. Might look something like:
def check_permissions
raise CanCan::AccessDenied unless @current_user.role?(:admin)
end
If I just wanted to prevent access to update and create, for example, I would do:
def update
raise CanCan::AccessDenied unless can?(:update,Thing)
...
end
def create
raise CanCan::AccessDenied unless can?(:create,Thing)
...
end
You can handle the CanCan::AccessDenied
exception in your application controller:
rescue_from CanCan::AccessDenied do |exception|
flash[:error] = exception.message
redirect_to no_access_path
end
I have some pretty good posts about CanCan and Devise here and here
UPDATE I use this method in my application controller to set my current user variable:
# Make the current user object available to views
#----------------------------------------------------------------------------
def get_user
@current_user = session[:current_user]
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With