My favorite solution so far is having a JSON-encoded column with user permissions for the given table/object. I like it because I can wrap it up as a SQLAlchemy mixin and add it to declarative classes as needed, which was pretty much perfect for the project I used this solution on.
It really depends on your situation though (as it almost always does in programming). The main problem with the JSON-encoded column is that it becomes nasty when you need to list all the objects you have permissions for (this wasn't needed in my app). I have a feeling that you could work around this if you used recent versions of SQLAlchemy and Postgres, and used an HSTORE to store the JSON data. I have yet to try this out though. Having one giant table for permissions is really annoying, and in some cases a performance killer. It's especially bad if your db objects all have _different_ permissions, as you then have a very sparse table. It's easy to write code for, though, and whether the performance implications will really matter depend on the specific app (of course). Having one table per object could work pretty well, though you'd definitely want to package it up nicely. I think you could make it not too bad to work with, though it would take some significant effort to do so. Hmmm... I bet you'd want to create a SA mixin of some kind, that would register an SA event, so that the permissions table gets created whenever the object table gets created. Then the mixin would also add a bunch of addPermission/removePermission type methods for easy management of permissions. If you needed to make large updates you could drop down to a lower level of SA. I think I'd prefer the HSTORE solution, assuming that it can be made to work (and assuming Postgres), but the "associated table" solution could also work pretty well I think. -- Kevin Horn On Wed, Jan 2, 2013 at 12:41 AM, Michael Pedersen <[email protected]>wrote: > This is where I'm going to call it a night for me. I'll work on catching > up more tomorrow. > > My question for you is this: Are you looking for view based permissions > (i.e.: possibly conditional portions of the page being rendered), or are > you looking for row based permissions (i.e.: a specific instance of > model.Thing is only visible to a subset of users)? > > The first item is already covered very well by repoze.what predicates. You > can insert <py:if> statements in your code, and get the results you're > expecting. The second case, though, I don't know of a generic way to do it. > > I've considered adding some sort of decorator to SQLAlchemy model objects > where a new table will be defined, and each row of that table will contain > permissions information related to the row with the same primary key in the > main table. I've also considered adding a column with json encoded > permission information, and I've considered a single table which maintains > all permission information across all tables. > > None of these solutions appeal to me, though. The associated permissions > table becomes easy to bypass in code, and maintaining it is problematic: > What happens if group A is supposed to have permissions to an object, then > those permissions are revoked? That table would require an update, possibly > a large update. It's problematic at best. The same issues occur with the > other two options. > > I have yet to find a way that will properly connect the current > permissions information with all instances, and do so efficiently. Every > option has problems, especially with updates. > > Did you get anywhere with this? If so, how did you handle these issues? > How do you do the join so that people with permissions to see the objects > actually get to see them? Can you allow a group to contain a group, and the > container group's permissions propagate over? What about updates of tables > with a million rows? How does the system perform then? > > > On Wed, Nov 28, 2012 at 5:31 AM, Craig Small <[email protected]> wrote: > >> I got a system here where I need different users to be able to see >> different sets of things. >> >> So the simple setup at first is users in one specific group are the >> admins and can see all things, so the ThingController just checks to see >> if the user is in that group and its all good. >> >> Besides admins there are standard users. They should be only see the >> Things that are assigned to them and not even see anyone elses. My >> original idea was to have a group_id placed into the Thing's model and >> then in the controller have a check that: >> Thing.group_id in user's.groups >> or in sql SELECT * from things where group_id in (<groups user is in>) >> >> Is this the best way to do it? I may also need to use groups for other >> things (ie read-only admins or admins who can only see some screens) >> so groups would not just be used for limiting the Thing views. >> >> -- >> Craig Small VK2XLZ http://enc.com.au/ csmall at : enc.com.au >> Debian GNU/Linux http://www.debian.org/ csmall at : debian.org >> GPG fingerprint: 5D2F B320 B825 D939 04D2 0519 3938 F96B DF50 FEA5 >> >> -- >> You received this message because you are subscribed to the Google Groups >> "TurboGears" group. >> To post to this group, send email to [email protected]. >> To unsubscribe from this group, send email to >> [email protected]. >> For more options, visit this group at >> http://groups.google.com/group/turbogears?hl=en. >> >> > > > -- > Michael J. Pedersen > My Online Resume: http://www.icelus.org/ -- Google+ > http://plus.ly/pedersen > Google Talk: [email protected] -- Twitter: pedersentg > > -- > You received this message because you are subscribed to the Google Groups > "TurboGears" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/turbogears?hl=en. > -- -- Kevin Horn -- You received this message because you are subscribed to the Google Groups "TurboGears" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/turbogears?hl=en.

