__bobo_traverse__, restrictedTraverse and PageTemplates
I'm using Zope 2.5.1b1, CMF from CVS. I'm having a strange problem when trying to define a custom __bobo_traverse__, where an Unauthorized exception is raised from PageTemplates/Expressions.py/restrictedTraverse. The object's __bobo_traverse__ is simply doing def __bobo_traverse__(self, REQUEST, name): """Traversal to get to the virtual documents.""" target = getattr(self, name, None) if target is not None: return target #... other things that are never called ... (The goal would be to make some objects appear to be under a given level which isn't in fact a container but calls the catalog to display a listing.) With that code, if I try to view the object, I get: ... File .../lib/python/ZPublisher/Publish.py, line 39, in call_object (Object: foo) File .../Products/CMFCore/PortalContent.py, line 167, in __call__ (Object: foo) File .../lib/python/Shared/DC/Scripts/Bindings.py, line 252, in __call__ (Object: mylevel_view) File .../lib/python/Shared/DC/Scripts/Bindings.py, line 283, in _bindAndExec (Object: mylevel_view) File .../lib/python/Products/PageTemplates/Expressions.py, line 177, in _eval File .../lib/python/Products/PageTemplates/Expressions.py, line 134, in _eval (Info: here) File .../lib/python/Products/PageTemplates/Expressions.py, line 321, in restrictedTraverse (Object: foo) (Info: {'path': ['portal_url'], 'TraversalRequestNameStack': []}) Unauthorized: You are not allowed to access portal_url in this context There error stems from the fact that the view calls here/portal_url, which sould be ok. If I remove the bobo_traverse, everything works fine and dandy of course. I don't undersand the difference because my __bobo_traverse__ is just doing standard stuff that traversal would do anyway. If I look at Expressions.py/restrictedTraverse, there are discrepancies I cannot explain. The relevant parts in this case are (I commented the code that's not executed, for display purposes): t=get(object, '__bobo_traverse__', N) if t is not N: o=t(REQUEST, name) container = None #if has(o, 'im_self'): # container = o.im_self #elif (has(get(object, 'aq_base', object), name) # and get(object, name) == o): # container = object if not validate(object, container, name, o): raise Unauthorized, name # line 321 else: o=get(object, name, M) if o is not M: # Check security. if has(object, 'aq_acquire'): object.aq_acquire( name, validate2, validate) #else: # if not validate(object, object, name, o): # raise Unauthorized, name #else: # try: # o=object[name] # except (AttributeError, TypeError): # raise AttributeError, name # if not validate(object, object, name, o): # raise Unauthorized, name object = o So I don't understand the different treatments, with bobo_traverse I get a None container, which makes the validate fail, whereas standard traversal calls ac_acquire with as a filter validate2, the filters receives a container, and this validation suceeds. If anybody has any lights on how I write do the __bobo_traverse__ I need... Thanks, Florent -- Florent Guillaume, Nuxeo (Paris, France) +33 1 40 33 79 10 http://nuxeo.com mailto:fg@nuxeo.com
Florent Guillaume wrote:
So I don't understand the different treatments, with bobo_traverse I get a None container, which makes the validate fail, whereas standard traversal calls ac_acquire with as a filter validate2, the filters receives a container, and this validation suceeds.
If anybody has any lights on how I write do the __bobo_traverse__ I need...
I'm assuming you're using TALES traversal as opposed to ZPublisher traversal, right? It lets you view the objects directly through the web, doesn't it? Have you considered implementing __getitem__() instead of __bobo_traverse__()? __bobo_traverse__() is messy. I'm inclined to tell you the restrictedTraverse() method is wrong, and that container should be computed as the aq_inner of the aq_parent, but we something might depend on the current behavior. Shane
Shane Hathaway <shane@zope.com> wrote:
If anybody has any lights on how I can write the __bobo_traverse__ I need...
I'm assuming you're using TALES traversal as opposed to ZPublisher traversal, right? It lets you view the objects directly through the web, doesn't it?
Yes, TALES traversal. Actually I didn't even get to see the object through the web because the error occured in the view method.
Have you considered implementing __getitem__() instead of __bobo_traverse__()?
No I hadn't, but I should have ! Thanks for the idead, for my needs it does the job perfectly.
I'm inclined to tell you the restrictedTraverse() method is wrong, and that container should be computed as the aq_inner of the aq_parent, but we something might depend on the current behavior.
I believe it's wrong too, but at this point there's too much voodoo in these parts of Zope that it'll take Zope 3 to clean all that up :) Florent -- Florent Guillaume, Nuxeo (Paris, France) +33 1 40 33 79 10 http://nuxeo.com mailto:fg@nuxeo.com
participants (2)
-
Florent Guillaume -
Shane Hathaway