# How to extend UserEngine to provide roles on a per project b

**URL:** <https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306>\
**Category:** Engines\
**Created:** [April 20, 2006, 1:16pm UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306 "2006-04-20T13:16:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [April 20, 2006, 1:16pm UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/1 "2006-04-20T13:16:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [April 20, 2006, 7:30pm UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/2 "2006-04-20T19:30:17Z")

</div>

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  
> removed\_email\_address@domain.invalid  
> [http://lists.rails-engines.org/listinfo.cgi/engine-users-rails-engines.org](http://lists.rails-engines.org/listinfo.cgi/engine-users-rails-engines.org)

\_Kevin

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [April 20, 2006, 7:58pm UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/3 "2006-04-20T19:58:14Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [April 20, 2006, 9:24pm UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/4 "2006-04-20T21:24:51Z")

</div>

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)

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [May 17, 2006, 1:45am UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/5 "2006-05-17T01:45:57Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [May 15, 2006, 12:04am UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/6 "2006-05-15T00:04:28Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![prichard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/90db22/32.png) [@prichard](https://www.ruby-forum.com/u/prichard)\
**Post date:** [May 17, 2006, 7:14am UTC](https://www.ruby-forum.com/t/how-to-extend-userengine-to-provide-roles-on-a-per-project-b/58306/7 "2006-05-17T07:14:41Z")

</div>

Hi,

I dont’l know if it is a ‘match’ for you, but have you looked at  
ActiveRBAC  
[https://activerbac.turingstudio.com/trac](https://activerbac.turingstudio.com/trac) ?
