[Zope-Coders] please review LocalRolesRevamp

Shane Hathaway shane@zope.com
Tue, 09 Oct 2001 17:36:37 -0400


Martijn Faassen wrote:

> Shane Hathaway wrote:
> 
>>One of the nice features of CMF is that it filters search results based 
>>on what you're allowed to view.  It does this by cataloging the list of 
>>roles that are allowed to access the object.  Then when you perform a 
>>search it injects a filter into the query that limits what you see based 
>>on your roles.
>>
>>Simplifying for a moment, say the cataloged field is called 
>>"allowedRoles", you have an object "A", and the roles allowed to access 
>>"A" are ["Manager", "Reviewer"].  When user "R", who has the roles 
>>"Reviewer" and "Authenticated", performs a search, the catalog will add 
>>to the query a filter that matches any of the roles ["Reviewer", 
>>"Authenticated"].  Object "A" matches, so if the other criteria match as 
>>well, it will be returned.
>>
> 
> Finding objects based on the user permission is nice. I assume it's
> already a scalability problem to do a postprocessing run over the
> returned objects to see if they're accessible by the user doing the
> query?


Yep.

> It sounds like you'd run into a similar problem each time you want 
> catalog data that is somehow dependent on the context the object is
> in, though, isn't it? For instance, if an object acquires an attribute
> 'color' that you want to catalog, which is 'green' at time of cataloguing,
> and then you change the acquired attribute to something else, your catalog
> is going to contain wrong information. Of course in that case it'd be wrong for
> all users, not just for the user with the local roles.. But this is
> more of an aside; I'm sure you've considered these topics better than
> I have, so I'm just thinking out loud.


This is a fundamental issue with caching in general.  The solution is 
usually an invalidation protocol.  Zope doesn't have one yet.

>>This gets messy when you consider local roles.  Today, the CMF catalog 
>>has an "allowedRolesAndUsers" field.  It contains not only the global 
>>roles that are allowed to access the object, but also the IDs of users 
>>who are allowed to access it based on their local roles (prefixed by 
>>"user:").  When a user performs a search, the filter that is added to 
>>the query contains, in addition to the list of the user's roles, the ID 
>>of the user, prefixed by "user:".
>>
>>If you think about it, this strategy works, but has a couple of lurking 
>>problems.  They might be major problems for some people.
>>
>>  - You have to be able to precompute the entire list of users who can 
>>access an object.  That might not be possible in some environments. (LDAP?)
>>
> 
> Yes, I'm in an LDAP environment with thousands of users. Some of these
> users will get roles in some areas based on some of their information
> (where in the organization they work, etc). Lots of this information is
> already inside the LDAP database, and computable local roles seem to be
> a good way to get this out, and map it to different rocal roles in
> different areas of the site.


Will you provide a search form that filters by access?  You may need it.

>>  - If you use local roles to set up areas for workgroups, every object 
>>stored in the workgroup folder is going to have to be cataloged with the 
>>name of every user who can access it.  That could be a scalability issue 
>>if there are a lot of people in the workgroup and they manage a lot of 
>>objects.
>>
> 
> If local roles are also used for the role that has view permission in some
> areas (which may be hundreds of users), then I'd run into trouble there
> too, I expect.
> 
> Of course I am still not convinced one can or should catalog such dynamic
> context-dependent things as roles..


It depends on how dynamic you consider object roles to be.  It's 
unlikely your objects' roles change very often, unless you're using CMF 
workflow, in which case it's not a problem since objects get reindexed 
every time object roles change.

>>So how can we deal with this?  Well, what if local roles were stored on 
>>the user object instead of in the object hierarchy?  To populate the 
>>qualifiedRoles query, we would ask the user object for the complete list 
>>of qualified roles the user has.
>>
> 
>>This would have a couple of nice bonuses.  Since all roles would be 
>>managed by the user folder, people would be able to manage all user 
>>roles in one place.  An administrator would be able to look at *one* 
>>screen to see what a user can access.
>>
> 
> Yes, that would be nice, but in my case what a user can access is
> managed outside Zope; if someone's data changes in the LDAP database,
> or whatever the user data source is, that person may suddenly be able to
> access different areas of the site.

> 
> What this means is that the restricted areas of the site would 
> know themselves what kind of attributes a user should have for this
> user to have a particular role. If the user is in organization part A
> (stored in the external data source), that user should have the
> 'Manager' role in a particular section of the site. So you can't calculate
> a list of objects a user has access to without accessing the objects
> themselves; you need to ask if the user's set of metadatas has access
> to that particular area.
> 
> One could create roles for all organization parts, and then
> assign permissions for particular accesses in particular areas, but that'd
> create an unworkable amount of roles, so I think local roles are 
> still the best bet, if they could be more dynamically assigned.


Have you considered modifying the user folder implementation to achieve 
computed local roles?  Did you know that the only place local roles are 
computed is in the basic User class, which you can override?

>>There's a new catch, though.  When you catalog an object you have to be 
>>able to compute a list that will match all possible qualified roles. 
>>What if someone has the "WorkgroupMember" local role in the 
>>"/workgroups" folder?  That should grant them access to object "A".
>>
> 
> I think I just described this problem, with the added complication of
> dynamically computed local roles. And the trouble is still that
> even with the current local roles, who is assigned what roles where
> can change, invalidating your catalog. So I ask the philosophical
> question whether this is a problem you actually want to solve; 
> how much dynamism do we need to give up before something can be
> cataloged?


You're confusing object roles and user roles.  I can't think of a 
scenario where object roles change often, except when using workflow in 
the CMF, and luckily in the CMF objects are recataloged right after 
their workflow state changes.  You're talking about a site where *user* 
roles vary often.  What currently happens is user names are stored in 
the catalog, and I proposed taking out all user names and replacing them 
with object roles.  The catalog would only contain static information.

>>There are two answers to that question that I can see.  One is to create 
>>a special catalog index for the purpose of role-based filtering.  It 
>>would take into account the inheritance rules.
>>
> 
> Wouldn't work for computed local roles, though, right?


It could, actually.  Since the catalog would store object roles only, 
which don't change often, you would be in a better position than you are 
today to use computed local roles.

>>Another option is to 
>>populate the qualifiedRoles field with all permutations of object 
>>ancestor paths and roles.  Object "A" might be indexed with 9 
>>qualifiedRoles.  This isn't *too* bad since the number of qualifiedRoles 
>>probably won't reach triple digits.  (I can explain that better if you 
>>like, but the special catalog index is probably a better option.)
>>
> 
> I'm somewhat out of my depth here, I think. 
> 
> 
>>So, in summary...
>>
>>I would like to move all local role storage and management to the user 
>>folders.  It would make it easier to administrate a system and would 
>>make CMF more scalable.
>>
> 
> It would however eliminate my chances to use computed local roles, though,
> right?

> 
> Hmm, I think there's also another problem.
> 
> You'd also lose some other scalability as you'd disallow users
> who don't have access to a user folder to manage local roles. Right now,
> I can be a Manager in some folder and assign local roles to various other
> people in the area I manage. In your proposal you'd have a problem
> similar to what we have with ZClasses now; you can only create them
> if you have management access to the entire site. Here, only people with
> access to the user folder can manage local roles, which would seem
> to severely degrade ones ability to delegate user management.


No.  That's more a user interface issue, really.  Local roles might be 
managed centrally but modified in place.

> Anyway, again, the philosophical tradeoff; in order to catalog things
> better you give up some flexility and power. I'm not sure that is
> worth it; by definition you can't catalog context-dependent and dynamic
> meta data very well.


Think of the catalog more like a *cache* and it makes a lot of sense. 
It's the Zope equivalent of Unix "locate" and the CMF catalog is the 
equivalent of "slocate".

Shane