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.

Reply via email to