[Zope3-checkins] SVN: Zope3/branches/dominik-locatableadapters/src/zope/app/ clean up code:

Dominik Huber dominik.huber at projekt01.ch
Mon May 2 06:53:40 EDT 2005


Log message for revision 30225:
  clean up code:
  - remove unused classes
  - move tests to adapter.txt

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

-=-
Modified: Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py	2005-05-02 07:44:19 UTC (rev 30224)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/component/metaconfigure.py	2005-05-02 10:53:40 UTC (rev 30225)
@@ -29,7 +29,7 @@
 from zope.security.proxy import Proxy
 
 from zope.app import zapi
-from zope.app.security.adapter import PartiallyLocatingTrustedAdapterFactory
+from zope.app.security.adapter import LocatingTrustedAdapterFactory
 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 = PartiallyLocatingTrustedAdapterFactory(factory)
+        factory = LocatingTrustedAdapterFactory(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 = PartiallyLocatingTrustedAdapterFactory(factory)
+        factory = LocatingTrustedAdapterFactory(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/security/adapter.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py	2005-05-02 07:44:19 UTC (rev 30224)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.py	2005-05-02 10:53:40 UTC (rev 30225)
@@ -21,210 +21,14 @@
 from zope.app.location import ILocation, Location, LocationProxy
 
 
-class TrustedAdapterFactoryMixin(object):
-    """Adapt an adapter factory to to provide trusted 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 (S) unless the adapted object were unproxied
-    before (N).
-
-    We account two different base use cases S (security-proxied) and N
-    (not security-proxied).
-
-        S.  security proxy > adapter > object(s)
-        N.  adapter > object(s)
-        R.  adapter > security proxy(s) > object(s) (Untrusted adapters)
-
-    Suppose we have an adapter factory:
-
-        >>> class A(object):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-    Now, suppose have an object and proxy it:
-
-        >>> o = []
-        >>> p = ProxyFactory(o)
-
-    If we adapt it the result is regularly (R) not security-proxied
-    but the object it adapts still is:
-
-        >>> a = A(p)
-        >>> type(a).__name__
-        'A'
-        >>> type(a.context).__name__
-        '_Proxy'
-
-    Now, will we will adapt our adapter factory to a trusted adapter factory
-    mixin:
-
-        >>> TA = TrustedAdapterFactoryMixin(A)
-
-    S. Adaption of security-proxied objects
-    If we use it the adapter is security-proxied, but it adapts anymore.
-    (We actually have to remove the adapter to get to the adapted object
-    in this case.):
-
-        >>> a = TA(p)
-        >>> type(a).__name__
-        '_Proxy'
-        >>> a = removeSecurityProxy(a)
-        >>> type(a).__name__
-        'A'
-        >>> type(a.context).__name__
-        'list'
-
-    This works with multiple objects too:
-
-        >>> class M(object):
-        ...     def __init__(self, *context):
-        ...         self.context = context
-
-        >>> TM = TrustedAdapterFactoryMixin(M)
-
-        >>> o2 = []
-        >>> o3 = []
-
-        >>> a = TM(p, o2, o3)
-        >>> type(a).__name__
-        '_Proxy'
-        >>> a = removeSecurityProxy(a)
-        >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
-        (True, True, True)
-
-        >>> a = TM(p, ProxyFactory(o2), ProxyFactory(o3))
-        >>> type(a).__name__
-        '_Proxy'
-        >>> a = removeSecurityProxy(a)
-        >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
-        (True, True, True)
-
-    N. Adaption of none-security-proxied objects
-    In cases where the first object that should be adapted is not
-    security-proxied the resulting adapter is not security-proxied too:
-
-        >>> a = TA(o)
-        >>> type(a).__name__
-        'A'
-        >>> type(a.context).__name__
-        'list'
-
-        >>> a = TM(o, o2, o3)
-        >>> type(a).__name__
-        'M'
-        >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
-        (True, True, True)
-
-    The factory adapter has the __name__ and __module__ of the
-    factory it adapts:
-
-        >>> (TA.__module__, TA.__name__) == (A.__module__, A.__name__)
-        True
-
-    """
-    def __init__(self, factory):
-        self.factory = factory
-        self.__name__ = factory.__name__
-        self.__module__ = factory.__module__
-
-    # protected methods
-    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._customizeProtected(adapter, args[0])
-                return ProxyFactory(adapter)
-
-        adapter = self.factory(*args)
-        adapter = self._customizeUnprotected(adapter, args[0])
-        return adapter
-
-
 def assertLocation(adapter, parent):
     """Assert locatable adapters.
 
     This function asserts that the adapter get location-proxied unless it does
     not provide ILocation itself. Further more the returned locatable adapter
     get its parent set unless its __parent__ attribute is not None.
-    
-    Arguments
-    ---------
-    adapter - unproxied adapter
-    parent - unproxied locatable object
 
-    Usage
-    -----
-    Suppose we have a location that plays the duty-parent in cases
-    where no regular-parent is provided by the adapter itself:
-
-        >>> dutyparent = Location()
-
-    We account three different base use cases A, B and C.
-    
-    A. Adapters which do not provide ILocation get location-proxied
-    and theirs parent is set to the duty-parent:
-
-        >>> class A(object):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-        >>> a = A(dutyparent)
-        >>> a1 = assertLocation(a, dutyparent)
-
-        >>> ILocation.providedBy(a1)
-        True
-        >>> a1.__parent__ is dutyparent
-        True
-        >>> type(a1).__name__
-        'LocationProxy'
-
-    B. Adapters which do provide ILocation get never location-proxied,
-    but theirs parent is also set to the duty-parent unless their parent is
-    not None:
-
-        >>> class B(Location):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-        >>> b = B(dutyparent)
-        >>> b1 = assertLocation(b, dutyparent)
-
-        >>> ILocation.providedBy(b1)
-        True
-        >>> b1.__parent__ is dutyparent
-        True
-        >>> type(b1).__name__
-        'B'
-
-    C. In those cases where the parent is provided by the adapter itself, the
-    adapter keeps its regular-parent:
-
-        >>> regularparent = Location()
-
-        >>> class C(Location):
-        ...     def __init__(self, context):
-        ...         self.context = context
-        ...         self.__parent__ = context
-
-        >>> c = C(regularparent)
-        >>> c1 = assertLocation(c, dutyparent)
-
-        >>> ILocation.providedBy(c1)
-        True
-        >>> c1.__parent__ is regularparent
-        True
-        >>> type(c1).__name__
-        'C'
+    see adapter.txt
     """
     # handle none-locatable adapters (A)
     if not ILocation.providedBy(adapter):
@@ -242,116 +46,30 @@
         return adapter
 
 
-# BBB: The trusted adapter factory is replaced by the locating trusted adapter
-# factory
-class TrustedAdapterFactory(TrustedAdapterFactoryMixin):
-    """Adapt an adapter factory to to provide trusted adapters
+class LocatingTrustedAdapterFactory(object):
+    """Adapt an adapter factory to provide trusted and (locatable) adapters.
 
-    Trusted adapters always adapt unproxied objects.  If asked to
+    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.
+    security-proxy the resulting adapter (S) unless the objects where not
+    security-proxied before (N).
 
-    Further this adapter factory sets the __parent__ attribute of locatable
-    object (ILocation) unless those objects do not provide their parent
-    itself.
+    Further locating trusted adapters provide a location for protected
+    adapters only (S). If such a protected adapter itself does not provide
+    ILocation it is wrapped within a location proxy and it parent will 
+    be set. If the adapter does provide ILocation and it's __parent__ is None,
+    we set the __parent__ to the adapter's context: 
 
-    We account three different base use cases A, B and C (corresponding 
-    to def assertLocation()) each of them provided two variantions S and
-    N corresponding to class TrustedAdapterFactoryMixin).
-
-    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 = TrustedAdapterFactory(A)
-
-    AS. Security-proxied:
-
-        >>> a = TA(p)
-        >>> a.__parent__
-        Traceback (most recent call last):
-        ...
-        AttributeError: 'A' object has no attribute '__parent__'
-        >>> type(a).__name__
-        '_Proxy'
-
-    AN. None-security-proxied:
-
-        >>> a = TA(o)
-        >>> a.__parent__
-        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 = TrustedAdapterFactory(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 = TrustedAdapterFactory(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'
+    see adapter.txt
     """
+    def __init__(self, factory):
+        self.factory = factory
+        self.__name__ = factory.__name__
+        self.__module__ = factory.__module__
 
+    # protected methods
     def _customizeProtected(self, adapter, context):
-        if (ILocation.providedBy(adapter)
-            and adapter.__parent__ is None):
-                    adapter.__parent__ = context
-        return adapter
+        return assertLocation(adapter, context)
 
     def _customizeUnprotected(self, adapter, context):
         if (ILocation.providedBy(adapter)
@@ -359,243 +77,37 @@
                     adapter.__parent__ = context
         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._customizeProtected(adapter, args[0])
+                return ProxyFactory(adapter)
 
-class LocatingTrustedAdapterFactory(TrustedAdapterFactoryMixin):
-    """Adapt an adapter factory to to provide trusted locatable adapters
+        adapter = self.factory(*args)
+        adapter = self._customizeUnprotected(adapter, args[0])
+        return adapter
 
-    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 always provide a location.
-    If an adapter itself does not provide ILocation it is wrapped 
-    within a location proxy and it parent will be set:
+# BBB, entire class gone in 3.2 
+class TrustedAdapterFactory(LocatingTrustedAdapterFactory):
+    """Adapt an adapter factory to provide trusted adapters.
 
-        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 = LocatingTrustedAdapterFactory(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
-        True
-        >>> type(a).__name__
-        'LocationProxy'
-        >>> type(removeAllProxies(a)).__name__
-        'A'
-
-    B. Locatable, but parentless adapters
-
-        >>> class B(Location):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-
-        >>> TB = LocatingTrustedAdapterFactory(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 = LocatingTrustedAdapterFactory(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):
-        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'
+    we set the __parent__ to the adapter's context.
     """
 
+    # do not location-proxy the adapter
     def _customizeProtected(self, adapter, context):
-        return assertLocation(adapter, context)
+        return self._customizeUnprotected(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
 
@@ -605,82 +117,11 @@
     correctly.
 
     If the adapter does not provide ILocation, we location proxy it and
-    set the parent:
-    
-        location proxy > adapter > security proxy > object(s) 
-    
-    If the adapter does provide ILocation and it's __parent__ is None,
-    we set the __parent__ only:
+    set the parent. If the adapter does provide ILocation and 
+    it's __parent__ is None, we set the __parent__ to the adapter's
+    context only:
 
-        adapter > security proxy > object(s)
-
-    Now, suppose have an object and proxy it:
-
-      o = []
-      >>> o = []
-      >>> p = ProxyFactory(o)
-
-    A. Adapters which do not provide ILocation get location-proxied
-    and theirs parent is set:
-
-        >>> class A(object):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-        >>> UA = LocatingUntrustedAdapterFactory(A)
-        >>> a = UA(o)
-
-        >>> ILocation.providedBy(a)
-        True
-        >>> a.__parent__ is o
-        True
-        >>> type(a).__name__
-        'LocationProxy'
-        >>> from zope.proxy import removeAllProxies
-        >>> type(removeAllProxies(a)).__name__
-        'A'
-
-    B. Adapters which do provide ILocation get never location-proxied,
-    but theirs parent is also set unless their parent is
-    not None:
-
-        >>> class B(Location):
-        ...     def __init__(self, context):
-        ...         self.context = context
-
-        >>> UB = LocatingUntrustedAdapterFactory(B)
-        >>> b = UB(o)
-
-        >>> ILocation.providedBy(b)
-        True
-        >>> b.__parent__ is o
-        True
-        >>> type(b).__name__
-        'B'
-
-    C. In those cases where the parent is provided by the adapter itself,
-    nothing happens:
-
-        >>> class C(Location):
-        ...     def __init__(self, context):
-        ...         self.context = context
-        ...         self.__parent__ = context
-
-        >>> UC = LocatingUntrustedAdapterFactory(C)
-        >>> c = UC(o)
-
-        >>> ILocation.providedBy(c)
-        True
-        >>> c.__parent__ is o
-        True
-        >>> type(c).__name__
-        'C'
-
-     The factory adapter has the __name__ and __module__ of the
-     factory it adapts:
-
-         >>> (UB.__module__, UB.__name__) == (B.__module__, B.__name__)
-         True
+    see adapter.txt
     """
 
     def __init__(self, factory):

Added: Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.txt
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.txt	2005-05-02 07:44:19 UTC (rev 30224)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.txt	2005-05-02 10:53:40 UTC (rev 30225)
@@ -0,0 +1,388 @@
+===================================
+def assertLocation(adapter, parent)
+===================================
+
+This function asserts that the adapter get location-proxied unless it does
+not provide ILocation itself. Further more the returned locatable adapter
+get its parent set unless its __parent__ attribute is not None.
+
+Arguments
+---------
+adapter - unproxied adapter
+parent - unproxied locatable object
+
+Usage
+-----
+Suppose we have a location that plays the duty-parent in cases
+where no regular-parent is provided by the adapter itself:
+
+    >>> from zope.app.location import Location
+    >>> from zope.app.location.interfaces import ILocation
+    >>> dutyparent = Location()
+
+We account three different base use cases A, B and C.
+
+A. Adapters which do not provide ILocation get location-proxied
+and theirs parent is set to the duty-parent:
+
+    >>> class A(object):
+    ...     def __init__(self, context):
+    ...         self.context = context
+
+    >>> a = A(dutyparent)
+    
+    >>> from zope.app.security import adapter
+    >>> a1 = adapter.assertLocation(a, dutyparent)
+
+    >>> ILocation.providedBy(a1)
+    True
+    >>> a1.__parent__ is dutyparent
+    True
+    >>> type(a1).__name__
+    'LocationProxy'
+
+B. Adapters which do provide ILocation get never location-proxied,
+but theirs parent is also set to the duty-parent unless their parent is
+not None:
+
+    >>> class B(Location):
+    ...     def __init__(self, context):
+    ...         self.context = context
+
+    >>> b = B(dutyparent)
+    >>> b1 = adapter.assertLocation(b, dutyparent)
+
+    >>> ILocation.providedBy(b1)
+    True
+    >>> b1.__parent__ is dutyparent
+    True
+    >>> type(b1).__name__
+    'B'
+
+C. In those cases where the parent is provided by the adapter itself, the
+adapter keeps its regular-parent:
+
+    >>> regularparent = Location()
+
+    >>> class C(Location):
+    ...     def __init__(self, context):
+    ...         self.context = context
+    ...         self.__parent__ = context
+
+    >>> c = C(regularparent)
+    >>> c1 = adapter.assertLocation(c, dutyparent)
+
+    >>> ILocation.providedBy(c1)
+    True
+    >>> c1.__parent__ is regularparent
+    True
+    >>> type(c1).__name__
+    'C'
+
+
+=============================
+LocatingTrustedAdapterFactory
+=============================
+
+General Trusted Adapter Mechanism
+---------------------------------
+
+Trusted adapters always adapt unproxied objects. If asked to
+adapt any proxied objects, it will unproxy them and then security-proxy
+the resulting adapter (S) unless the adapted object were unproxied
+before (N).
+
+We account two different base use cases S (security-proxied) and N
+(not security-proxied).
+
+    S.  security proxy > adapter > object(s)
+    N.  adapter > object(s)
+    R.  adapter > security proxy(s) > object(s) (Untrusted adapters)
+
+Suppose we have an adapter factory:
+
+    >>> class A(object):
+    ...     def __init__(self, context):
+    ...         self.context = context
+
+Now, suppose have an object and proxy it:
+
+    >>> from zope.security.checker import ProxyFactory
+
+    >>> o = []
+    >>> p = ProxyFactory(o)
+
+If we adapt it the result is regularly (R) not security-proxied
+but the object it adapts still is:
+
+    >>> a = A(p)
+    >>> type(a).__name__
+    'A'
+    >>> type(a.context).__name__
+    '_Proxy'
+
+Now, will we will adapt our adapter factory to a trusted adapter factory
+mixin:
+
+    >>> TA = adapter.LocatingTrustedAdapterFactory(A)
+
+S. Adaption of security-proxied objects
+If we use it the adapter is security-proxied, but it adapts anymore.
+(We actually have to remove the adapter to get to the adapted object
+in this case.):
+
+    >>> a = TA(p)
+    >>> type(a).__name__
+    '_Proxy'
+    
+    >>> from zope.security.proxy import removeSecurityProxy
+    >>> a = removeSecurityProxy(a)
+    >>> type(a).__name__
+    'LocationProxy'
+    >>> type(a.context).__name__
+    'list'
+
+This works with multiple objects too:
+
+    >>> class M(object):
+    ...     def __init__(self, *context):
+    ...         self.context = context
+
+    >>> TM = adapter.LocatingTrustedAdapterFactory(M)
+
+    >>> o2 = []
+    >>> o3 = []
+
+    >>> a = TM(p, o2, o3)
+    >>> type(a).__name__
+    '_Proxy'
+    >>> a = removeSecurityProxy(a)
+    >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
+    (True, True, True)
+
+    >>> a = TM(p, ProxyFactory(o2), ProxyFactory(o3))
+    >>> type(a).__name__
+    '_Proxy'
+    >>> a = removeSecurityProxy(a)
+    >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
+    (True, True, True)
+
+N. Adaption of none-security-proxied objects
+In cases where the first object that should be adapted is not
+security-proxied the resulting adapter is not security-proxied too:
+
+    >>> a = TA(o)
+    >>> type(a).__name__
+    'A'
+    >>> type(a.context).__name__
+    'list'
+
+    >>> a = TM(o, o2, o3)
+    >>> type(a).__name__
+    'M'
+    >>> a.context[0] is o, a.context[1] is o2, a.context[2] is o3
+    (True, True, True)
+
+The factory adapter has the __name__ and __module__ of the
+factory it adapts:
+
+    >>> (TA.__module__, TA.__name__) == (A.__module__, A.__name__)
+    True
+
+
+Locating Trusted Adapters
+-------------------------
+
+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 (S) unless the objects where not
+security-proxied before (N).
+
+Further locating trusted adapters provide a location for protected
+adapters only (S). 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 = adapter.LocatingTrustedAdapterFactory(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 = adapter.LocatingTrustedAdapterFactory(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 = adapter.LocatingTrustedAdapterFactory(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'
+
+Locating Untrusted Adapters
+---------------------------
+
+Untrusted adapters always adapt proxied objects. If any permission
+other than zope.Public is required, untrusted adapters need a location
+in order that the local authentication mechanism can be inovked
+correctly.
+
+If the adapter does not provide ILocation, we location proxy it and
+set the parent:
+
+    location proxy > adapter > security proxy > object(s) 
+
+If the adapter does provide ILocation and it's __parent__ is None, 
+we set the __parent__ to the adapter's context only:
+
+    adapter > security proxy > object(s)
+
+Now, suppose have an object and proxy it:
+
+  o = []
+  >>> o = []
+  >>> p = ProxyFactory(o)
+
+A. Adapters which do not provide ILocation get location-proxied
+and theirs parent is set:
+
+    >>> class A(object):
+    ...     def __init__(self, context):
+    ...         self.context = context
+
+    >>> UA = adapter.LocatingUntrustedAdapterFactory(A)
+    >>> a = UA(o)
+
+    >>> ILocation.providedBy(a)
+    True
+    >>> a.__parent__ is o
+    True
+    >>> type(a).__name__
+    'LocationProxy'
+    >>> from zope.proxy import removeAllProxies
+    >>> type(removeAllProxies(a)).__name__
+    'A'
+
+B. Adapters which do provide ILocation get never location-proxied,
+but theirs parent is also set unless their parent is
+not None:
+
+    >>> class B(Location):
+    ...     def __init__(self, context):
+    ...         self.context = context
+
+    >>> UB = adapter.LocatingUntrustedAdapterFactory(B)
+    >>> b = UB(o)
+
+    >>> ILocation.providedBy(b)
+    True
+    >>> b.__parent__ is o
+    True
+    >>> type(b).__name__
+    'B'
+
+C. In those cases where the parent is provided by the adapter itself,
+nothing happens:
+
+    >>> class C(Location):
+    ...     def __init__(self, context):
+    ...         self.context = context
+    ...         self.__parent__ = context
+
+    >>> UC = adapter.LocatingUntrustedAdapterFactory(C)
+    >>> c = UC(o)
+
+    >>> ILocation.providedBy(c)
+    True
+    >>> c.__parent__ is o
+    True
+    >>> type(c).__name__
+    'C'
+
+ The factory adapter has the __name__ and __module__ of the
+ factory it adapts:
+
+     >>> (UB.__module__, UB.__name__) == (B.__module__, B.__name__)
+     True


Property changes on: Zope3/branches/dominik-locatableadapters/src/zope/app/security/adapter.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/branches/dominik-locatableadapters/src/zope/app/security/tests/test_adapter.py
===================================================================
--- Zope3/branches/dominik-locatableadapters/src/zope/app/security/tests/test_adapter.py	2005-05-02 07:44:19 UTC (rev 30224)
+++ Zope3/branches/dominik-locatableadapters/src/zope/app/security/tests/test_adapter.py	2005-05-02 10:53:40 UTC (rev 30225)
@@ -16,13 +16,16 @@
 $Id$
 """
 import unittest
+
+from zope.testing import doctest
 from zope.testing.doctestunit import DocTestSuite
 
+
 def test_suite():
     return unittest.TestSuite((
         DocTestSuite('zope.app.security.adapter'),
+        doctest.DocFileSuite('../adapter.txt'),
         ))
 
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')
-



More information about the Zope3-Checkins mailing list