[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/pas/ Implemented delegation for getPrincipal and unauthorized methods of PAS.

Daniel Nouri dpunktnpunkt at web.de
Sat Oct 9 13:48:15 EDT 2004


Log message for revision 27867:
  Implemented delegation for getPrincipal and unauthorized methods of PAS.
  Added LocalPAS subclass of PAS, which is our local service.
  


Changed:
  U   Zope3/trunk/src/zope/app/pas/README.txt
  U   Zope3/trunk/src/zope/app/pas/__init__.py
  U   Zope3/trunk/src/zope/app/pas/pas.py


-=-
Modified: Zope3/trunk/src/zope/app/pas/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/README.txt	2004-10-09 17:43:10 UTC (rev 27866)
+++ Zope3/trunk/src/zope/app/pas/README.txt	2004-10-09 17:48:14 UTC (rev 27867)
@@ -21,7 +21,7 @@
 2. It constructs a principal from the given ID, combining information
    from a number of sources.
 
-It uses plug-ins in both phases of it's work. Plugins are named
+It uses plug-ins in both phases of its work. Plugins are named
 utilities that the service is configured to use in some order.
 
 In the first phase, the PAS iterates through a sequence of extractor
@@ -105,7 +105,7 @@
 Finally, we create a PAS instance:
 
   >>> from zope.app import pas
-  >>> service = pas.PAS()
+  >>> service = pas.LocalPAS()
 
 Now, we'll create a request and try to authenticate:
 
@@ -318,7 +318,33 @@
   >>> event.info
   {'domain': 42}
 
+Our PAS will not find a principal with the ID '123'. Therefore it will
+delegate to the next service. To make sure that it's delegated, we put in place
+a fake service.
 
+  >>> from zope.app.component.localservice import testingNextService
+  >>> from zope.app.site.interfaces import ISiteManager
+  >>> from zope.app import servicenames
+
+  >>> class FakeService:
+  ...
+  ...     zope.interface.implements(ISiteManager)
+  ...
+  ...     lastGetPrincipalCall = lastUnauthorizedCall = None
+  ...
+  ...     def getPrincipal(self, name):
+  ...         self.lastGetPrincipalCall = name
+  ...
+  ...     def unauthorized(self, id, request):
+  ...         self.lastUnauthorizedCall = id
+
+  >>> nextservice = FakeService()
+  >>> testingNextService(service, nextservice, servicenames.Authentication)
+
+  >>> service.getPrincipal('123')
+  >>> '123' == nextservice.lastGetPrincipalCall
+  True
+
 Issuing a challenge
 ===================
 
@@ -331,7 +357,12 @@
 
   >>> service.unauthorized(42, request)
 
-What happens if a plugin is registered depends on the plugin.  Lets
+However, our next service was asked:
+
+  >>> 42 == nextservice.lastUnauthorizedCall
+  True
+
+What happens if a plugin is registered depends on the plugin.  Let's
 create a plugin that sets a response header:
 
   >>> class Challenge:
@@ -371,7 +402,7 @@
 3. The view gets the authentication service and calls it's
    'unauthorized' method.
 
-4. The PAS will call it's challenge plugins.  If none return a value,
+4. The PAS will call its challenge plugins.  If none return a value,
    then the PAS delegates to the next authentication service above it
    in the containment hierarchy, or to the global authentication
    service.
@@ -385,9 +416,9 @@
 example, the HTTP specification allows multiple challenges to be isued
 in a response.  A challenge plugin can provide a `protocol`
 attribute.  If multiple challenge plugins have the same protocol,
-then, if any of them are caled and return True, then they will all be
+then, if any of them are called and return True, then they will all be
 called.  Let's look at an example.  We'll define two challengers that
-add chalenges to a X-Challenges headers:
+add challenges to a X-Challenges headers:
 
   >>> class ColorChallenge:
   ...     zope.interface.implements(interfaces.IChallengePlugin)
@@ -489,8 +520,3 @@
 =========
 
   XXX Still workin this out
-
-Delegation
-==========
-
-  XXX Still need to write this

Modified: Zope3/trunk/src/zope/app/pas/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/__init__.py	2004-10-09 17:43:10 UTC (rev 27866)
+++ Zope3/trunk/src/zope/app/pas/__init__.py	2004-10-09 17:48:14 UTC (rev 27867)
@@ -17,4 +17,4 @@
 """
 
 import interfaces
-from zope.app.pas.pas import PAS
+from zope.app.pas.pas import PAS, LocalPAS

Modified: Zope3/trunk/src/zope/app/pas/pas.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/pas.py	2004-10-09 17:43:10 UTC (rev 27866)
+++ Zope3/trunk/src/zope/app/pas/pas.py	2004-10-09 17:48:14 UTC (rev 27867)
@@ -19,9 +19,16 @@
 from zope.event import notify
 import zope.interface
 import zope.schema
+from persistent import Persistent
 
 from zope.app import zapi
 
+from zope.app.servicenames import Authentication
+from zope.app.component.localservice import queryNextService
+from zope.app.container.contained import Contained
+from zope.app.site.interfaces import ISimpleService
+from zope.app.location.interfaces import ILocation
+
 from zope.app.pas import vocabularies, interfaces
 from zope.app.pas.interfaces import IExtractionPlugin
 from zope.app.pas.interfaces import IAuthenticationPlugin
@@ -115,7 +122,7 @@
 
     def getPrincipal(self, id):
         if not id.startswith(self.prefix):
-            return
+            return self._delegate('getPrincipal', id)
         id = id[len(self.prefix):]
 
         for searcher in self.searchers:
@@ -129,6 +136,8 @@
 
             return self._create('createFoundPrincipal', self.prefix+id, info)
 
+        return self._delegate('getPrincipal', self.prefix+id)
+
     def unauthenticatedPrincipal(self):
         pass
 
@@ -148,6 +157,14 @@
                     elif protocol is None:
                         protocol = challenger_protocol
 
-        # XXX Fallback code.  This will call unauthorized on higher-level
-        # authentication services.
+        return self._delegate('unauthorized', id, request)
+
+    def _delegate(self, meth, *args):
+        # delegate to next AS
+        next = queryNextService(self, Authentication, None)
+        if next is not None:
+            return getattr(next, meth)(*args)
         
+
+class LocalPAS(PAS, Persistent, Contained):
+    zope.interface.implements(IPAS, ILocation, ISimpleService)



More information about the Zope3-Checkins mailing list