Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization in Rails 3.1 : CanCan, CanTango, declarative_authorization?

I have looked at declarative_authorization, CanCan, and CanTango. They all are good in adding authorization to the application but I was wondering how does one add authorization to specific instance of a model i.e. a person can have a manage access in one project and only limited (read less than manage: limited update, etc) in another.

Could you please a better way? Apologies if my question sounds too trivial. It could be because I am new to RoR.

thanks, John

like image 276
Raj Lalwani Avatar asked Jan 18 '12 06:01

Raj Lalwani


1 Answers

As I know CanCan and declarative_authorization, and I implemented role-based authorizations with both, I recommend CanCan. Just my two cents.

Example (untested, unfortunately I cannot test here and I have no access to my code)

So let's say we have a structure like this:

class User < ActiveRecord::Base
  belongs_to :role
end

class Role < ActiveRecord::Base
  has_many :users

  # attributes: project_read, project_create, project_update
end

Then, CanCan could look like this:

class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user
    @role = user.role

    # user can see a project if he has project_read => true in his role
    can :read, Project if role.project_read? 

    # same, but with create
    can :create, Project if role.project_create?

    # can do everything with projects if he is an admin
    can :manage, Project if user.admin?
  end

end

You can find all information you need in the CanCan wiki on github. Personal recommendation to read:

  • https://github.com/ryanb/cancan/wiki/Defining-Abilities
  • https://github.com/ryanb/cancan/wiki/Defining-Abilities-with-Blocks
  • https://github.com/ryanb/cancan/wiki/Authorizing-Controller-Actions

Basically you just need to extend the example above to include your roles through your relations. To keep it simple, you can also create additional helper methods in ability.rb.

The main mean caveat you may fall for (at least I do): Make sure your user can do something with a model before you define what the user can't. Otherwise you'll sit there frustrated and think "but why? I never wrote the user can't.". Yeah. But you also never explicitly wrote that he can...

like image 140
pdu Avatar answered Nov 16 '22 08:11

pdu