Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting CanCan ability.rs model

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

like image 575
dormitkon Avatar asked Dec 28 '22 00:12

dormitkon


1 Answers

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
like image 67
Tony Avatar answered Jan 13 '23 04:01

Tony