Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic roles and permissions system in Rails app

I need to create roles based permissions systems in my Rails app. I would be totally happy with CanCan, but the main problem - it has to be dynamic, so that Admin has to be able to assign permissions and to create new roles. The permissions can be simple controller/action restrictions, and can be data related, for example some users can edit only their own profiles, and some of them can edit the profiles of all the users in the particular group. And it would be really nice to allow Admin to create new permissions.

What I'm thinking about is to store in db a controller/action, and some data related restrictions (I'm really confused here about the way to define them). So could you please give me some advice, what would be the best way to organize permissions?

Any thoughts are much appreciated

like image 430
alony Avatar asked Jan 06 '12 11:01

alony


People also ask

What is dynamic permission?

Domain-based Dynamic Access Control enables administrators to apply access-control permissions and restrictions based on well-defined rules that can include the sensitivity of the resources, the job or role of the user, and the configuration of the device that is used to access these resources.

What is a dynamic role?

Dynamic roles represent the system groups that are created for the roles assigned to team members in context teams and shared teams. The system groups created in an application context representing the organizations that have members in the context team.

What are the different types of user roles?

There are five main types of user roles in your school—the primary owner, owners, authors, affiliates, and students.

What is user roles and permissions?

User Roles give Administrators the ability to control what users can do within the system, without giving full administrator access. A Role is a collection of Permissions which could be based on a job function. Permissions are assigned to Roles and Roles are assigned to Users.


2 Answers

If you like CanCan, then I think is best to use it. Here is a short tutorial about storing abilities in database so non-programmers can update them:

https://github.com/ryanb/cancan/wiki/Abilities-in-Database

If you really, really want to implement such system yourself. Depending on your needs, I will suggest for you to implement it as simple as possible.

In the case you need only users to have access to modules(certain controllers). You can do:

  1. Store all users permissions in just like serialized fields -> http://apidock.com/rails/ActiveRecord/Base/serialize/class

    class User serialize :permissions, Array

    def access_to?(module) permissions.include? module.to_s end end

some check when setting this field would be nice.

  1. Just make a check on top of every controller if the current user have access to this controller(section)

    class ApplicationController private

    def self.require_access_to(module)
       before_filter do |c|
         unless c.send(:current_user).try :access_to?(module)
           c.send :render_no_presmissions_page
         end
       end
    end
    

    end

    class AdminNewsController require_access_to :news end

Of course this is just a start position, from where you can easily evolve.

like image 134
Radoslav Stankov Avatar answered Sep 22 '22 11:09

Radoslav Stankov


[EDIT The link given by @RadoslavStankov is a better answer than this.]

You can do it with CanCan easily. Just make a model for permissions (which has_and_belongs_to_many :users), and in your Ability#initialize load the permissions appropriate to the user from the model and say that the user can do them. Then make appropriate user interface for administrating that model.

Something like this:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    user.permissions.each do |permission|
      can permission.symbol, permission.scope
    end
    user.prohibitions.each do |permission|
      cannot permission.symbol, permission.scope
    end
  end
end

where scope returned something like :all for nil scope, or Object.const_get(@scope_name) otherwise... Play with it. Anyway, it's doable.

More complex CanCan things are likely to be more complex (duh) - for example conditional permissions - but that would be a bitch to administer as well, so I think this should be enough for most applications.

like image 34
Amadan Avatar answered Sep 23 '22 11:09

Amadan