[Zope-Coders] please review LocalRolesRevamp

Martijn Faassen faassen@vet.uu.nl
Wed, 10 Oct 2001 01:03:51 +0200


Shane Hathaway wrote:
> Martijn Faassen wrote:
> This is a fundamental issue with caching in general.  The solution is 
> usually an invalidation protocol.  Zope doesn't have one yet.

Right, though in fact the problem I described is harder; if you change
context you don't know what to invalidate, unless you invalidate *everything*
that may acquire the context. This is true for local roles. See
below for more detail on that.

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

I don't understand what you mean. Filter what by whose access?

I want to provide a mapping object that maps user meta data to local
roles. Since I don't know when the LDAP database changes, the local
roles should be dynamically recomputed. This removes a lot of hassle of
individual user management; you just say this kind of user gets this
role. Unless of course you can to assign local roles to particular users
and not to groups already extractable from the user source.

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

Two things can change: the user meta-data -> local role mapping in the 
special mapping object (that in my proposal would hook into 
__ac_local_roles__ of the folder it is in). This is in Zope. What
also can change is the underlying LDAP source. A person may be removed
from the organization or change place in the organization, or added.
I don't want to assign a new local role for this person in Zope; it
can simply look up the roles the user has in any particular place in the
mapping (i.e. by going to __ac_local_roles__ and asking for
the roles that particular user has given his meta data).

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

I've been looking through this code today and yesterday.

So you propose I implement my own User.allowed() method, not looking at 
__ac_local_roles__ at all (at least not for computed local roles)? I could
copy & paste allowed() and hack it up, but that seems like such a kludge.
It would also not improve Zope in any way. It would be hard to 
maintain as well; each time allowed() changes my own user object needs
to change. My proposal avoids all that; allowed() is only changed
once to deal with the new local roles interface (a small change) and
we do any particular computation we like behind that interface. 

> >>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'm talking about __ac_local_roles__, a dictionary which associates
user ids with roles, which is acquired by objects. I don't know if
they're user or object roles, but I'd say they're 'local roles'. :)

If user A receives a local role Manager in some folder close to the root
in the tree, the catalog is likely to become wrong for that user when 
he queries it, right? It would return far less objects that it should,
because when the object was cataloged the user could not access a lot
of objects that he now can.

The catalog cannot be aware this user now has that extra role for those 
objects, unless you update the catalog for all objects in that folder 
each time a local role is set for a user in that 
folder, which seems excessive (and precludes computed local roles).

You can fix this by maintaining local roles in the user object itself
and using a special catalog index that knows about acquisition of local
roles when determining if someone has access, as you propose (right?).
As you say later, there could (and should) still be management methods 
hooking into this associated with the folders itself, otherwise
only people with access to the user folder can change local roles
settings. I was initially confused about this, as you seemed to
imply the UI would be in the user folder at first.

Perhaps I'm misunderstanding something.

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

If I understand you right, yes, I am. I wasn't talking about object
roles. Sorry if I confused them.

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

Right; if I understand you right, the object roles are already in there,
and the usernames are just a hack to make local roles work.

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

Except that they need to be computed relative to the objects in
the tree.. i.e. to know if I have computed local role X for object
Y, I need to ask object Y first for its particular user metadata ->
local role mapping (which it'll try to find using acquisition and by
going up in the tree). Thus, in order to compute the list of roles I
have for particular paths in the site, I would need to access *all*
the paths in the site to ask what its particular mapping of 
user meta data to local roles is.

Take the use case that I want for some reason associate access with
IP number. When a user has an IP number in a particular range, he
can access folder B as he gains a local role with permissions to do so.

If you compute local roles locally, you can easily do this; you 
ask __ac_local_roles__ "given this user and this REQUEST, what 
roles does this user have here?".

Now, in my use case it's not even dependent on REQUEST (which makes
things completely unpredictable), but on user meta data. So you
say "given this user meta data, what roles does this user have here?"

As far as I can see it you can't compute this without actually asking
the objects you're trying to access.

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

As I said before; I got confused as you seemed to say they'd be managed
(in the UI sense) in the user folder. You'd need both an API and
user interface in the folders themselves to manage local roles still
in the new case.

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

What does slocate do? I don't have it on my system, apparently. :) 
A locate with security checks? Anyway, what I'm saying is that
we are dealing with a tradeoff here; we're asking how much 
flexibility should we give up in order to cache better. 

Your solution (storing local roles in the user object instead of
on the folder, combined with the fancy cache indexes that know about roles)
would maintain the current functionality with regards to local roles, 
and would allow better caching.

What I need however is more than the current functionality allows, and I can
see a way to give local roles quite a bit more flexibility by allowing
them to be computed. Storing local roles in the user object would make this
hard to do, as far as I can see. And I don't quite see how else to
reach my goals, which do not seem unreasonable. I could of course give
up and store local roles for groups in Zope directly, computing them
and caching the results in Zope, only improving the management screens to 
make the management of these a bit easier..

Regards,

Martijn