OK, I've not seen anything out there on this, but maybe you guys can make a suggestion. I have Users, and they of course have Roles. However, the Roles they have are not global, they are only in place for certain Projects. There are some Roles that are generic - e.g. a 'General User' role applies to all Users, irrespective of Project So, a user might be a 'Manager' for one project and a 'Designer' on another project. I need to be able to simply manage this process and over-ride stuff in lib like link_if_authorized. I have spent two days writing code, it's an absolute mess, and I think it's because I'm not thinking clearly about how to handle what is in effect a 3-way HABTM relationship: Projects HABTM Users, Users HABTM Roles, Roles HABTM Projects. As a result, I'm not going to paste any code here - just curious if anybody has any ideas about how they would approach this to help me clear my head. -- Paul R.
on 2006-04-20 15:16
on 2006-04-20 21:30
I've thought about this a bit, and there are a couple of ways to deal with it. The simplest I can think of is to add a project_id column to the permissions table. Let it default to NULL, which means that if a permission is set then it applies across all projects the user has access to. The project_id could either be a real association to a project, or just a yaml encoded list of valid projects. Then you need to override the authorization functions to use this value as well, so your calls might look like. link_if_authorized 'action', :controller=>'cont', :action=>'action', :project=>proj.id You would also need to set up the permission entries view to handle multiple projects for assignment. This could get really messy, or you could have an admin view on a per project basis. On Thursday, April 20, 2006, at 12:15 PM, Paul R. wrote: > >clear my head. > >-- >Paul R. > > >_______________________________________________ >engine-users mailing list >email@example.com >http://lists.rails-engines.org/listinfo.cgi/engine... _Kevin
on 2006-04-20 21:58
On 20 Apr 2006, at 18:29, Kevin O. wrote: > The simplest I can think of is to add a project_id column to the > permissions table. That's interesting. Because I've specified it on the users_roles table. I'm thinking users have roles in projects. Your approach though... hmmmm... > Let it default to NULL, which means that if a > permission is set then it applies across all projects the user has > access to. The project_id could either be a real association to a > project, or just a yaml encoded list of valid projects. Project is < ActiveRecord::Base so making it a real association is sensible. > Then you need to override the authorization functions to use this > value > as well, so your calls might look like. > > link_if_authorized 'action', :controller=>'cont', :action=>'action', > :project=>proj.id Yeah, that's what I was thinking. > You would also need to set up the permission entries view to handle > multiple projects for assignment. This could get really messy, or you > could have an admin view on a per project basis. I'm thinking the latter. Where I got really stuck is that I'm trying to manage a 3-way HABTM relationship, so when I'm managing the roles a user has, I'm trying to @user.projects.roles.each do |role| ... which of course just doesn't work. I think I need to have a think about your suggestion but it might work - I suspect I'm going to end up back here again but with permissions rather than roles. I think when I have more time after this project is over, I'm going to extend UserEngine somewhat to provide this kind of functionality - I'm just confused about the best way to do it right now. :-) -- Paul R.
on 2006-04-20 23:24
I'm in a very similar situation myself. I have the same three way join between users, roles, and sections (equivalent to your projects). I've been calling this an assignment (for want of a better name) in that a user is 'assigned' a role for a section. I'm not doing this with the user engine but the problem is effectively the same. For each role you can set a permission for a variety of action verbs (not Rails actions but the more general sense of the word). So for example you can create a 'contributor' that can view all stuff, add new stuff, edit their own stuff, delete their own stuff and so on. Basically for each action you can either do nothing (i.e. no permissions), perform the action on only items you own, or perform the action on all items. The list of actions is a bit generalised as I didn't want to have to create a rule for each and every controller action I ever come up with. In effect you need to determine which action verb is appropriate when applying a permission test. For example I might have a 'classify' action verb that could be used to determine if a user can apply tags or place an item in a category. This means you can't get as granular as you might want to bit it does simplify things. I then have an admin page where you can select which role a user should be given for each 'section' including an option to have no role (i.e. no entry in the assignment relationship). In my user model I have methods like @user.can_edit?(@some_section) and @user.can_delete?(@section) which I think read quite nicely. Behind the scenes this looks up the relevant assignment for the user for the section in question and then inspects the role to see if the user can do the required action. I've been thinking about making this use method_missing so the @user.can_xxx? stuff is all neat and tidy. The xxx bit equates to the action verb and the underlying code is the same regardless of the actual action being tested. The hardest part is actually applying all the permission tests everywhere they need to be - and this is the part I'm currently in the midst of. I'm using a similar 'link_to_if' approach which works OK in the view but can get messy when there are a lot of things to protect. My HTML is looking less and less like HTML and more and more like ruby. Then there's obviously the need to ensure a user can't just bypass a link in the page and format a request to do something they are not allowed to. Before_filters help to a point here but I'm finding that often times the permission logic needs to be deeper within a controllers action. I've also come across problems where I allow batch editing of items. For example deleting from a list of items by selecting a check-box next to the relevant items and then hitting a delete button. Problem is that you might have rights to delete some of the items but not others. I can't just hide the check-box in such cases as I also use them to allow batch enabling/disabling of items from the same list. You might have permission to delete some items and enable/disable others. There's no way to accurately hide/show the correct check-boxes as they are very likely to clash Doubt my rambling helps to clear your head but it felt good getting it all out ;o)
on 2006-05-15 02:04
Paul, You probably want to have some has_many :through style association, i.e. User has many Roles through ProjectPosition, or something like that. - james
on 2006-05-17 03:45
On 14 May 2006, at 23:01, James A. wrote: > Paul, > > You probably want to have some has_many :through style association, > i.e. User has many Roles through ProjectPosition, or something like > that. It gets more complicated than that. I did manage to finally do it by effectively passing some data around, but it's still not perfect. When I get a spare day or three, I think I'm going to look at either extending user_engine properly or building something from scratch to make this kind of work much easier in future. -- Paul R.
on 2006-05-17 09:14
Hi, I dont'l know if it is a 'match' for you, but have you looked at ActiveRBAC https://activerbac.turingstudio.com/trac ?