[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/tree/ Make the static tree recognize the permissions.

Roger Ineichen roger at projekt01.ch
Sat Mar 19 21:14:41 EST 2005


Log message for revision 29590:
  Make the static tree recognize the permissions.
  Show only items we can access

Changed:
  U   Zope3/trunk/src/zope/app/tree/TODO.txt
  U   Zope3/trunk/src/zope/app/tree/adapters.py
  U   Zope3/trunk/src/zope/app/tree/tests/test_adapters.py

-=-
Modified: Zope3/trunk/src/zope/app/tree/TODO.txt
===================================================================
--- Zope3/trunk/src/zope/app/tree/TODO.txt	2005-03-20 00:38:33 UTC (rev 29589)
+++ Zope3/trunk/src/zope/app/tree/TODO.txt	2005-03-20 02:14:40 UTC (rev 29590)
@@ -9,6 +9,9 @@
 - add XML representation so it's compatible with rotterdam's
   xmltree.js, but stateful
 
+Done for z3 release 3.1
+-----------------------
+
 - Catch Unauthorized exception and don't add items we don't have permission
   for accessing. This makes it possible to use the cookie tree without 
   zope.ManageSite permission. Right now the cookie tree access the ++etc++site

Modified: Zope3/trunk/src/zope/app/tree/adapters.py
===================================================================
--- Zope3/trunk/src/zope/app/tree/adapters.py	2005-03-20 00:38:33 UTC (rev 29589)
+++ Zope3/trunk/src/zope/app/tree/adapters.py	2005-03-20 02:14:40 UTC (rev 29590)
@@ -22,6 +22,8 @@
 """
 from zope.interface import Interface, implements
 from zope.component.exceptions import ComponentLookupError
+from zope.security import canAccess
+from zope.security.interfaces import Unauthorized
 
 from zope.app import zapi
 from zope.app.location.interfaces import ILocation
@@ -52,7 +54,7 @@
         return False
 
     def getChildObjects(self):
-        return ()
+        return []
 
 class LocationUniqueId(object):
     implements(IUniqueId)
@@ -79,10 +81,21 @@
         self.context = context
 
     def hasChildren(self):
-        return bool(len(self.context))
+        # make sure we check for access
+        try:
+            lenght = bool(len(self.context))
+            if lenght > 0:
+                return True
+            else:
+                return False
+        except Unauthorized:
+            return False
 
     def getChildObjects(self):
-        return self.context.values()
+        if self.hasChildren():
+            return self.context.values()
+        else:
+            return []
 
 class ContainerSiteChildObjects(ContainerChildObjects):
     """Adapter for read containers which are sites as well. The site
@@ -93,15 +106,42 @@
     def hasChildren(self):
         if super(ContainerSiteChildObjects, self).hasChildren():
             return True
-        try:
-            self.context.getSiteManager()
+        if self._canAccessSiteManager():
             return True
-        except ComponentLookupError:
+        else:
             return False
 
     def getChildObjects(self):
-        values = super(ContainerSiteChildObjects, self).getChildObjects()
+        if self.hasChildren():
+            values = super(ContainerSiteChildObjects, self).getChildObjects()
+            if self._canAccessSiteManager():
+                return [self.context.getSiteManager()] + list(values)
+            else:
+                return values
+        else:
+            return []
+
+    def _canAccessSiteManager(self):
         try:
-            return [self.context.getSiteManager()] + list(values)
+            # the ++etc++ namespace is public this means we get the sitemanager
+            # without permissions. But this does not mean we can access it
+            # Right now we check the __getitem__ method on the sitemamanger
+            # but this means we don't show the ++etc++site link if we have
+            # registred views on the sitemanager which have other permission
+            # then the __getitem__ method form the interface IReadContainer
+            # in the LocalSiteManager.
+            # If this will be a problem in the future, we can add a 
+            # attribute to the SiteManager which we can give individual 
+            # permissions and check it via canAccess.
+            sitemanager = self.context.getSiteManager()
+            authorized = canAccess(sitemanager, '__getitem__')
+            if authorized:
+                return True
+            else:
+                return False
         except ComponentLookupError:
-            return values
+            return False
+        except TypeError:
+            # we can't check unproxied objects, but unproxied objects
+            # are public.
+            return True

Modified: Zope3/trunk/src/zope/app/tree/tests/test_adapters.py
===================================================================
--- Zope3/trunk/src/zope/app/tree/tests/test_adapters.py	2005-03-20 00:38:33 UTC (rev 29589)
+++ Zope3/trunk/src/zope/app/tree/tests/test_adapters.py	2005-03-20 02:14:40 UTC (rev 29590)
@@ -19,6 +19,8 @@
 
 from zope.interface import implements, directlyProvides
 from zope.component.exceptions import ComponentLookupError
+from zope.security.checker import defineChecker
+from zope.security.checker import NamesChecker
 
 from zope.app.location.interfaces import ILocation
 from zope.app.container.interfaces import IReadContainer
@@ -52,6 +54,12 @@
         except AttributeError:
             raise ComponentLookupError
 
+class SiteManagerStub(object):
+    """This stub is used for to check the permission on __getitem__."""
+
+    def __getitem__(key):
+        return 'nada'
+
 class AdapterTestCase(PlacelessSetup, unittest.TestCase):
 
     def setUp(self):
@@ -66,6 +74,8 @@
         self.makeObjects()
 
     def makeObjects(self):
+        checker = NamesChecker(['__getitem__'])
+        defineChecker(SiteManagerStub, checker)
         self.futurama = futurama = SampleSite()
         directlyProvides(futurama, IContainmentRoot)
         planetexpress = SampleContainer()
@@ -149,7 +159,7 @@
         self.assertEqual(adapter.getChildObjects(), [])
 
     def test_container_site(self):
-        sm = object()
+        sm = SiteManagerStub()
         futurama = self.futurama
         omicronpersei = self.futurama['omicronpersei']
 



More information about the Zope3-Checkins mailing list