Approach on handling Access Control List and Permissions

Hello,

I am currently working on an app where I have at least 7 roles. I want to control all the permissions available for each role. Right now I have a users table, roles table and a joined table user_roles. I have 3 ideas in mind and will like to hear your opinion on both of them (and suggestions for better solutions).

The first one is having a models table that contains the following columns:

id model_name 1 User 2 Event 3 Post

and a joined table model_roles:

id role_id model_id Permission 1 1 1 15 2 3 3 2

The permission column will be a 4-bit number, each bit representing a CRUD operation, for example:

CRUD 0010 = 2

Meaning that the user with role_id 3 can only make updates on the Post model. The only problem I have found with this approach is that there might be other actions apart from the CRUD ones.

The other idea is an aro - aco based one (like the way CakePHP handles ACL's)

having a table with all the possible actions and another one establishing a relationship between role and the action

i.e.

aco's table

id aco 1 users 2 users/index

permissions table

role_id aco_id 1 1 1 2

... etc

the problem with this approach is that it will be a pain to keep these tables updated along with the permissions.

The other idea is to have an actions table that will contain the name of a controller and a action

id controller_name action_name 1 events new

and finally a roles_actions table id role_id action_id 1 1 2

The idea will be to query if the current_user can do an action on a specific controller. The problem with this approach is that there will be constant querying on the roles and roles_actions table every time a user tries to access any action on the app.

Anyone has ideas on how to diminish this? Maybe uploading permissions and rights for roles on a class on memory, uploading the permissions for a specific controller on a session (security problems?).

Any ideas or suggestions for of these, or better solutions?

Kind regards,

Elioncho

I had the same requirement. I used a similar approach to your option 2 above. I then used the Rails.cache facility in Rails 2.1 to cache permitted actions at login for each user. I have the before filter fetch from cache and not from the DB. I also have an active record call back after save on the "role" model to delete the Rails.cache if the role that is being saved is associated with users that have an active cache.