[Grok-dev] Data modelling & security
faassen at startifact.com
Thu Jan 20 17:06:41 EST 2011
On 01/17/2011 02:34 AM, Matthias wrote:
> 1) Does the basic version or the alternative version make more sense? The
> alternative version clearly marks any missing data. I am not sure if
> that's good or bad.
I'm not sure I understand the intent of the tables you mention. I mean,
if Task and User are accessible, why would you return the task and the
user? Is that because the assignment is inaccessible and you're actually
querying for assignments? Could you model this then so that the
Assignment permissions are the only ones directly checked, but you let
them derive from the underlying task and user (and their own permission)?
> 2) Each intermediate query result would need to be security checked. If
> you think checking the resulting objects sufficed, just imagine the
> results of the following query: "get any user where task == 'top secret'".
> You'd get a list of users involved with that task even if though nobody
> should've known that those users were assigned to the task.
The question is whether this is in fact a query for a user at all. Isn't
this really a query for "get all assignments where task == "top secret"?
From the assignments you can derive the users, yes, but is this really
the target of the query?
Anyway, I think it'd be interesting to set up at least a custom
PermissionMap for Assignment, and perhaps the others.
from zope.securitypolicy.interfaces import IPrincipalPermissionMap
from zope.security.management import checkPermission
# this is really the only method you have to implement, even though
# the interface defines more....
def getSetting(self, permission_id, principal_id, default=Unset)
if not checkPermission(permission_id, self.context.user):
You probably have to watch out for crazy recursion issues in some cases,
so perhaps instead of checkPermission you should go to a lower-level.
> 3) Resulting from 2) there might arise performance problems. I am not sure
> if the query could be performed while collecting the necessary permissions
> for each "row" in the result. Then one could check permissions only at the
> end (and possibly against some form of index to speed things up or the
> "top 10" of the results).
I think doing the permission checks in the end is a lot easier to get
right, and probably will perform better too.
> 4) If a user is generally accessible, it should not return the "password"
> attribute of the User except if the user is the querying user. I guess
> this can be solved with zope.proxy/zope.security. Or by turning the
> password attribute to a "PasswordProtected" relation between a user and
> its password, then the relation can be protected at the object level, just
> like the Assignment
You could of course try solving this issue in the user interface as
opposed to on the code level. The question here you have is how much do
you trust the developers. Do you really not trust them enough to want to
hide the password attribute? Is that either because they're too evil
(okay, give up already) or because they're too stupid?
> How do you guys deal with these problems? I'd really like avoid having to
> write a special grok.View and explicitly checking permissions for each
> operation the client might perform. If the queries could be all dynamic I
> could a) develop faster, b) had less redundant code and c) clients could
> create their own UIs/queries for their tasks.
I've recently mostly had to deal with these problems when exposing
SQLAlchemy objects, and PermissionMap works pretty well then. You can do
whatever database query you need to determine whether someone has a
You could do something similar: instead of using Zope's permissions you
could instead use your own database structures (attributes) to talk
about permissions in a way that is sensible to your application, and
then use PermissionMap to translate these to permissions so that views
show up or not. You could then use these attributes in your queries
You should only go for heavy-duty security proxies if you really don't
trust your developers in some way. There's not a lot of experience with
dealing this in a Grok context, but you should be able to make it work.
You might have to disable Grok's custom publisher.
I know it's tempting to get the security architecture right at a lower
level. Zope 3 (and the ZTK) was designed to allow this kind of stuff,
using the proxies. When we started the Grok project, I argued much for
loosening some of these rules, because getting the security model right
up-front (for all your methods and attributes) ends to take up a lot of
time and effort that can really be a drag on development, and during
early development you often don't even know enough about your data model
yet to get it right. A lot of usability issues...
That said, it might be possible to design a more lower level security
system that is more usable. It might also be that in some projects, the
investment in effort in the existing system is worth it.
> Additionally, are there any comparable systems which feature full objects
> like the ZODB does, yet allowing fully dynamic queries with fine-grained
> security? It might be worth "stealing" from them :-)
> Is it even advisable to be able to query the ZODB in the way outlined
It's a matter of trade-offs.
> Finally, is anybody else interested in features like this? Right now it
> seems this could make your client side coding a lot easier, especially if
I guess you're not satifisfied by just making sure your JSON methods are
protected and don't deliver too much data? :)
Thanks for bringing up this discussion! It's hard to get into, but it's
More information about the Grok-dev