Hello everyone,
I'm designing a system that has the next entities:
User, Project, Activity. Project has many Activities. Projects are managed by many users. Projects are leaded by many users. Activities are assigned to many users.
I have different roles like project_leader, project_manager and admin. I need to define roles and permissions on these entities so the admin can change them. Here's how it'll work:
Roles and permissions are going to be static. But the permissions assigned to a role won't be. Also the basic CRUD operations can be done in many different scopes: all projects, projects managed by me, projects leaded by me, activities in projects managed by me, activities assigned to me, etc.
I was thinking to define the permissions table like this:
name |
operation |
context |
context_attribute |
user_attribute |
compare_by |
Create projects |
create |
project |
|
|
|
Read all projects |
read |
project |
|
|
|
Update all projects |
update |
project |
|
|
|
Delete all projects |
delete |
project |
|
|
|
Update managed projects |
update |
project |
managers |
user |
contains |
Delete managed projects |
delete |
project |
managers |
user |
contains |
Update leaded projects |
update |
project |
leaders |
user |
contains |
Delete leaded projects |
delete |
project |
leaders |
user |
contains |
Create activity in any project |
create |
activity |
|
|
|
Read activities in any project |
read |
activity |
|
|
|
Update activities in any project |
update |
activity |
|
|
|
Delete activities in any project |
delete |
activity |
|
|
|
Create activity in managed projects |
create |
activity |
project |
user.managing_projects |
is_in |
Update acitivity in managed project |
update |
activity |
project |
user.managing_projects |
is_in |
Delete activity in managed projects |
delete |
activity |
project |
user.managing_projects |
is_in |
Create activity in leaded projects |
create |
activity |
project |
user.leading_projects |
is_in |
Update activity in leading projects |
update |
activity |
project |
user.leading_projects |
is_in |
Delete activities in leading projects |
delete |
activity |
project |
user.leading_projects |
is_in |
Update assigned activities |
update |
activity |
assigned |
user |
contains |
Delete assigned activities |
delete |
activity |
assigned |
user |
contains |
And try this in the authorization_rules file:
Role.all.each do | r |
role r.name.to_sym do
r.permissions.all.each do | p |
has_permission_on p.context.to_sym , :to => p.operation.to_sym do
if p.context_attribute
if_attribute p.context_attribute.to_sym => [ p.compare_by.to_sym , eval(p.user_attribute) ]
end
end
end
end
I'm not sure on the querys I used to consult permissions but I think the idea is there.
I haven't prove it yet because I'm still doing a lot of documentation but do you think it'll work?