Tres Seaver wrote:

I don't get it:  why isn't OFS.Traversable's check sufficient?
__bobo_traverse__ has a bad enough (insane, actually) contract, without
adding security checking to it.

Tres: You're quite right, the security check happens outside of bobo_traverse.

Dylan: Could you try this patch and see if it works for you. It really
needs some tests writing for it too.

Laurence

Index: Products/CMFCore/Skinnable.py
===================================================================
--- Products/CMFCore/Skinnable.py       (revision 87827)
+++ Products/CMFCore/Skinnable.py       (working copy)
@@ -27,6 +27,10 @@
 from Globals import InitializeClass
 from OFS.ObjectManager import ObjectManager
 from ZODB.POSException import ConflictError
+from zExceptions import NotFound
+import webdav
+from zope.interface import implements, Interface
+from zope.component import queryMultiAdapter
 
 logger = logging.getLogger('CMFCore.Skinnable')
 
@@ -94,6 +98,56 @@
         if superGetAttr is None:
             raise AttributeError, name
         return superGetAttr(self, name)
+    
+    def __bobo_traverse__(self, REQUEST, name):
+        '''
+        Ensures that views are traversed before skin objects
+        '''
+        resource = _marker = _MARKER
+        
+        # Look up unskinned objects
+        unskinned = super(SkinnableObjectManager, aq_base(self))
+        next = getattr(unskinned, name, _marker)
+        if next is _marker:
+            try:
+                try:
+                    next = self[name]
+                    # The item lookup may return a NullResource,
+                    # if this is the case we save it and return it
+                    # if all other lookups fail.
+                    if isinstance(next,
+                                  webdav.NullResource.NullResource):
+                        resource = next
+                        raise KeyError(name)
+                except (TypeError, AttributeError):
+                        # Raise NotFound for easier debugging
+                        # instead of AttributeError: __getitem__
+                        raise NotFound(name)
+                        
+            except (AttributeError, NotFound, KeyError), e:
+                # Try to look for a view
+                next = queryMultiAdapter((self, self.REQUEST),
+                                         Interface, name)
+                if next is not None:
+                    return next.__of__(self)
+    
+                # Lookup skin objects
+                next = getattr(aq_base(self), name, _marker)
+                if next is not _marker:
+                    return next
+        
+                # Try acquired attributes
+                next = getattr(self, name, _marker)
+                if next is not _marker:
+                    return next
+        
+                if next is _marker:
+                    # If we have a NullResource from earlier use it.
+                    next = resource
+                    if next is _marker:
+                        # Nothing found re-raise error
+                        raise e
+        return next
 
     security.declarePrivate('getSkin')
     def getSkin(self, name=None):
_______________________________________________
Zope-CMF maillist  -  Zope-CMF@lists.zope.org
http://mail.zope.org/mailman/listinfo/zope-cmf

See http://collector.zope.org/CMF for bug reports and feature requests

Reply via email to