[Zope3-checkins] SVN: Zope3/branches/dominik-locatableadapters/src/zope/app/ Only use a location proxy if the trusted adapter is protected and does not provide ILocation.

Dominik Huber dominik.huber at projekt01.ch
Wed Apr 20 17:46:38 EDT 2005


Log message for revision 30067:
  Only use a location proxy if the trusted adapter is protected and does not provide ILocation.

Changed:
  U   Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py
  U   Zope3/branches/dominik-locatableadapters/src/zope/app/component/tests/test_directives.py
  U   Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py

-=-
Modified: Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py	2005-04-20 20:57:53 UTC (rev 30066)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py	2005-04-20 21:46:38 UTC (rev 30067)
@@ -29,7 +29,7 @@
 from zope.security.proxy import Proxy
 
 from zope.app import zapi
-from zope.app.security.adapter import LocatingTrustedAdapterFactory
+from zope.app.security.adapter import PartiallyLocatingTrustedAdapterFactory
 from zope.app.security.adapter import LocatingUntrustedAdapterFactory
 
 PublicPermission = 'zope.Public'
@@ -115,7 +115,7 @@
     # invoke custom adapter factories
     if trusted:
         # trusted adapters that requires dedicated permission all the time
-        factory = LocatingTrustedAdapterFactory(factory)
+        factory = PartiallyLocatingTrustedAdapterFactory(factory)
 
     elif permission is not None and permission is not CheckerPublic:
         # untrusted adapters that requires any dedicated permission
@@ -186,7 +186,7 @@
     # invoke custom adapter factories
     if trusted:
         # trusted adapters that requires dedicated permission all the time
-        factory = LocatingTrustedAdapterFactory(factory)
+        factory = PartiallyLocatingTrustedAdapterFactory(factory)
 
     elif permission is not None and permission is not CheckerPublic:
         # untrusted adapters that requires any dedicated permission

Modified: Zope3/branches/dominik-locatableadapters/src/zope/app/component/tests/test_directives.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/component/tests/test_directives.py	2005-04-20 20:57:53 UTC (rev 30066)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/component/tests/test_directives.py	2005-04-20 21:46:38 UTC (rev 30067)
@@ -184,8 +184,7 @@
               />
             '''
             )))
-        # The adapter is location-proxied
-        # With an unproxied object
+        # With an unproxied object, business as usual
         content = Content()
         a1 = A1()
         subscribers = zapi.subscribers((content, a1), IS)
@@ -193,7 +192,7 @@
         a3 = subscribers[0]
 
         self.assertEqual(a3.__class__, A3)
-        self.assertEqual(type(a3).__name__, 'LocationProxy')
+        self.assertEqual(type(a3).__name__, 'A3')
         self.assertEqual(a3.context, (content, a1))
 
         # Now with a proxied object:
@@ -345,11 +344,9 @@
             '''
             )))
 
-        # With an unproxied object, a location proxied adapter is returned
+        # With an unproxied object, business as usual
         ob = Content()
-        self.assertEqual(type(I1(ob)).__name__, 'LocationProxy')
-        from zope.proxy import removeAllProxies
-        self.assertEqual(type(removeAllProxies(I1(ob))).__name__, 'A1')
+        self.assertEqual(type(I1(ob)).__name__, 'A1')
 
         # Now with a proxied object:
         from zope.security.checker import ProxyFactory

Modified: Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py	2005-04-20 20:57:53 UTC (rev 30066)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py	2005-04-20 21:46:38 UTC (rev 30067)
@@ -129,20 +129,24 @@
         self.__module__ = factory.__module__
 
     # protected methods
-    def _customize(self, adapter, context):
+    def _customizeProtected(self, adapter, context):
         """Subclasses might overwrite this method."""
         return adapter
 
+    def _customizeUnprotected(self, adapter, context):
+        """Subclasses might overwrite this method."""
+        return adapter
+
     def __call__(self, *args):
         for arg in args:
             if removeSecurityProxy(arg) is not arg:
                 args = map(removeSecurityProxy, args)
                 adapter = self.factory(*args)
-                adapter = self._customize(adapter, args[0])
+                adapter = self._customizeProtected(adapter, args[0])
                 return ProxyFactory(adapter)
 
         adapter = self.factory(*args)
-        adapter = self._customize(adapter, args[0])
+        adapter = self._customizeUnprotected(adapter, args[0])
         return adapter
 
 
@@ -343,12 +347,17 @@
         'C'
     """
 
-    def _customize(self, adapter, context):
+    def _customizeProtected(self, adapter, context):
         if (ILocation.providedBy(adapter)
             and adapter.__parent__ is None):
                     adapter.__parent__ = context
         return adapter
 
+    def _customizeUnprotected(self, adapter, context):
+        if (ILocation.providedBy(adapter)
+            and adapter.__parent__ is None):
+                    adapter.__parent__ = context
+        return adapter
 
 
 class LocatingTrustedAdapterFactory(TrustedAdapterFactoryMixin):
@@ -460,10 +469,133 @@
         'C'
     """
 
-    def _customize(self, adapter, context):
+    def _customizeProtected(self, adapter, context):
         return assertLocation(adapter, context)
 
+    def _customizeUnprotected(self, adapter, context):
+        return assertLocation(adapter, context)
 
+
+class PartiallyLocatingTrustedAdapterFactory(TrustedAdapterFactoryMixin):
+    """Adapt an adapter factory to to provide location for protected adapters
+
+    Trusted adapters always adapt unproxied objects. If asked to
+    adapt any proxied objects, it will unproxy them and then 
+    security-proxy the resulting adapter unless the objects where not
+    security-proxied before.
+
+    Further locating trusted adapters provide a location for protected
+    adapters only. If such a protected adapter itself does not provide
+    ILocation it is wrapped within a location proxy and it parent will 
+    be set:
+
+        security proxy > location proxy > adapter > object(s)
+
+    If the adapter does provide ILocation and it's __parent__ is None,
+    we set the __parent__ only: 
+    
+        security proxy > adapter > object(s) 
+
+    Now, suppose have an object and proxy it:
+
+        >>> o = []
+        >>> p = ProxyFactory(o)
+
+    A. Unlocatable adatpers
+
+        >>> class A(object):
+        ...     def __init__(self, context):
+        ...         self.context = context
+
+        >>> TA = PartiallyLocatingTrustedAdapterFactory(A)
+
+    AS. Security-proxied:
+
+        >>> a = TA(p)
+        >>> removeSecurityProxy(a.__parent__) is o
+        True
+        >>> type(a).__name__
+        '_Proxy'
+        >>> type(removeSecurityProxy(a)).__name__
+        'LocationProxy'
+        >>> from zope.proxy import removeAllProxies
+        >>> type(removeAllProxies(a)).__name__
+        'A'
+
+    AN. None-security-proxied:
+
+        >>> a = TA(o)
+        >>> a.__parent__ is o
+        Traceback (most recent call last):
+        ...
+        AttributeError: 'A' object has no attribute '__parent__'
+        >>> type(a).__name__
+        'A'
+
+    B. Locatable, but parentless adapters
+
+        >>> class B(Location):
+        ...     def __init__(self, context):
+        ...         self.context = context
+
+
+        >>> TB = PartiallyLocatingTrustedAdapterFactory(B)
+
+    BS. Security-proxied:
+
+        >>> a = TB(p)
+        >>> removeSecurityProxy(a.__parent__) is o
+        True
+        >>> type(a).__name__
+        '_Proxy'
+
+    BS. None-security-proxied:
+
+        >>> a = TB(o)
+        >>> a.__parent__ is o
+        True
+        >>> type(a).__name__
+        'B'
+
+    C. Locatable and parentful adapter
+
+        >>> marker = Location()
+
+        >>> class C(Location):
+        ...     def __init__(self, context):
+        ...         self.context = context
+        ...         self.__parent__ = marker
+
+
+        >>> TC = PartiallyLocatingTrustedAdapterFactory(C)
+
+    CS. Security-proxied:
+
+        >>> a = TC(p)
+        >>> removeSecurityProxy(a.__parent__) is marker
+        True
+        >>> type(a).__name__
+        '_Proxy'
+
+    CS. None-security-proxied:
+
+        >>> a = TC(o)
+        >>> a.__parent__ is marker
+        True
+        >>> type(a).__name__
+        'C'
+    """
+
+    def _customizeProtected(self, adapter, context):
+        return assertLocation(adapter, context)
+
+    def _customizeUnprotected(self, adapter, context):
+        if (ILocation.providedBy(adapter)
+            and adapter.__parent__ is None):
+                    adapter.__parent__ = context
+        return adapter
+
+
 class LocatingUntrustedAdapterFactory(object):
     """Adapt an adapter factory to provide locatable untrusted adapters
 



More information about the Zope3-Checkins mailing list