[Zope-Coders] please review LocalRolesRevamp

Martijn Faassen faassen@vet.uu.nl
Tue, 9 Oct 2001 22:40:21 +0200


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?

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 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.

>   - 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..
  
[snip]
> 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.

> 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?

> 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?

> 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.

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.

Regards,

Martijn