On 4/17/06, Dieter Maurer <dieter@handshake.de> wrote:
Alec Mitchell wrote at 2006-4-16 12:28 -0700:
... It seems that the way OFS.Traversable.restrictedTraverse() handles security checking on objects with __bobo_traverse__ methods is considerably different from the way it normally checks security. The result is that traversal cannot obtain attributes using acquisition from objects that are marked <five:traversable>. In the normal case, security is checked using guarded_getattr, which gets an attribute and checks the permissions on the retrieved object in its original context. For __bobo_traverse__methods which return simple properties (say strings), it is impossible to determine the container from which the returned attribute originates, so unless the attribute was not acquired, an Unauthorized error will always be raised. ... However, IMHO fixing this makes sense for Zope itself, provided there aren't any undesirable consequences. I propose that if the validation of a __bobo_traverse result raises Unauthorized, that we make one last check to see if the result o 'guarded_getattr(obj, name)' is identical to the result of the __bobo_traverse__ call and allow it if that's the case. Here is my proposed patch against Zope 2.9 trunk:
In our local Zope version, I implemented a solution that is (in my opinion) superior:
Define an exception "UseTraversalDefault" that can be used by "__bobo_traverse__" to tell the traversal process (either URL traversal in the publisher or restricted/unrestricted/CMF traversal) to use the default lookup.
One big advantage is that e.g. "Archetypes.BaseObject.BaseObject.__bobo_traverse__" no longer need this horrible dance to decide whether it should or must not create a "NullResource".
Yes, it does sound like a better solution. However, the issue I see with it is that it is essentially adding new functionality, rather than fixing a problem with the existing behavior. That would seem to make it a much less likely candidate for getting into zope 2.8.7 (which is important IMHO), despite the fact that it is a bit more elegant. In fact, I would say that even with this clever exception handling, there may still be cases where one wants to return an acquired attribute directly from a __bobo_traverse__, without simply falling back on the default behavior (say if one wants to limit the acquirable names or some other silly thing). So the two solutions can coexist peacefully; though the exception based solution is likely to allow a lot of nice simplifications to some of the hacky __bobo_traverses__ out there. Alec