[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/authentication/ Removed factory methods from authenticators. The PAU is now using the factory adapters directly.

Garrett Smith garrett at mojave-corp.com
Tue Mar 29 17:07:44 EST 2005


Log message for revision 29722:
  Removed factory methods from authenticators. The PAU is now using the factory adapters directly.
  

Changed:
  U   Zope3/trunk/src/zope/app/authentication/README.txt
  U   Zope3/trunk/src/zope/app/authentication/authentication.py
  U   Zope3/trunk/src/zope/app/authentication/groupfolder.py
  U   Zope3/trunk/src/zope/app/authentication/interfaces.py
  U   Zope3/trunk/src/zope/app/authentication/principalfolder.py
  U   Zope3/trunk/src/zope/app/authentication/tests.py

-=-
Modified: Zope3/trunk/src/zope/app/authentication/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/authentication/README.txt	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/README.txt	2005-03-29 22:07:44 UTC (rev 29722)
@@ -3,7 +3,7 @@
 ================================
 
 The Pluggable-Authentication Utility (PAU) provides a framework for
-authenticating principals and associating information with them. It uses 
+authenticating principals and associating information with them. It uses
 plugins and subscribers to get its work done.
 
 Authentication
@@ -13,11 +13,11 @@
 plug-ins in its work:
 
   - Credentials Plugins
-  
+
   - Authenticator Plugins
-  
-Credentials plugins are responsible for extracting user credentials from a 
-request. A credentials plugin may in some cases issue a 'challenge' to obtain 
+
+Credentials plugins are responsible for extracting user credentials from a
+request. A credentials plugin may in some cases issue a 'challenge' to obtain
 credentials. For example, a 'session' credentials plugin reads credentials
 from a session (the "extraction"). If it cannot find credentials, it will
 redirect the user to a login form in order to provide them (the "challenge").
@@ -26,12 +26,12 @@
 extracted by a credentials plugin. They are also typically able to create
 principal objects for credentials they successfully authenticate.
 
-Given a request object, the PAU returns a principal object, if it can. The PAU 
+Given a request object, the PAU returns a principal object, if it can. The PAU
 does this by first iterateing through its credentials plugins to obtain a
 set of credentials. If it gets credentials, it iterates through its
 authenticator plugins to authenticate them.
 
-If an authenticator succeeds in authenticating a set of credentials, the PAU 
+If an authenticator succeeds in authenticating a set of credentials, the PAU
 uses the authenticator to create a principal corresponding to the credentials.
 The authenticator notifies subscribers if an authenticated princiapl is created.
 Subscribers are responsible for adding data, especially groups, to the
@@ -77,13 +77,13 @@
   ...         if credentials == 'secretcode':
   ...             return principalfolder.PrincipalInfo('bob', 'Bob', '')
   ...
-  ...     def createAuthenticatedPrincipal(self, info, request):
+  ...     def createAuthenticatedPrincipal_XXX(self, info, request):
   ...         principal = principalfolder.Principal(info.id)
   ...         notify(interfaces.AuthenticatedPrincipalCreated(
   ...             principal, info, request))
   ...         return principal
   ...
-  ...     def createFoundPrincipal(self, info):
+  ...     def createFoundPrincipal_XXX(self, info):
   ...         principal = principalfolder.Principal(info.id)
   ...         notify(interfaces.FoundPrincipalCreated(principal, info))
   ...         return principal
@@ -96,6 +96,21 @@
 
   >>> provideUtility(MyAuthenticatorPlugin(), name='My Authenticator Plugin')
 
+Principal Factories
+-------------------
+While authenticator plugins provide principal info, they are not responsible
+for creating principals. This function is performed by factory adapters. For
+these tests we will register factories for creating both 'authenticated'
+principals:
+
+  >>> provideAdapter(principalfolder.AuthenticatedPrincipalFactory)
+
+and 'found' principals:
+
+  >>> provideAdapter(principalfolder.FoundPrincipalFactory)
+
+For more information on these factories, see their docstrings.
+
 Configuring a PAU
 -----------------
 Finally, we'll create the PAU itself:
@@ -247,13 +262,13 @@
 credentials. Specifically, the PAU went through these steps:
 
  - Get credentials using 'Form Credentials Plugin'
- 
- - Got 'hiddenkey' credentials using 'Form Credentials Plugin', try to 
+
+ - Got 'hiddenkey' credentials using 'Form Credentials Plugin', try to
    authenticate using 'My Authenticator Plugin'
-   
+
  - Failed to authenticate 'hiddenkey' with 'My Authenticator Plugin', try
    'My Authenticator Plugin 2'
- 
+
  - Succeeded in authenticating with 'My Authenticator Plugin 2'
 
 Let's try a different scenario:
@@ -264,13 +279,13 @@
 In this case, the PAU went through these steps:
 
   - Get credentials using 'Form Credentials Plugin'
-  
+
   - Failed to get credentials using 'Form Credentials Plugin', try
     'My Credentials Plugin'
-    
+
   - Got 'scecretcode' credentials using 'My Credentials Plugin', try to
     authenticate using 'My Authenticator Plugin'
-  
+
   - Succeeded in authenticating with 'My Authenticator Plugin'
 
 Let's try a slightly more complex scenario:
@@ -282,7 +297,7 @@
 This highlights PAU's ability to use multiple plugins for authentication:
 
   - Get credentials using 'Form Credentials Plugin'
-  
+
   - Got 'bogusvalue' credentials using 'Form Credentials Plugin', try to
     authenticate using 'My Authenticator Plugin'
 
@@ -294,10 +309,10 @@
     plugin for some new credentials
 
   - Get credentials using 'My Credentials Plugin'
-  
+
   - Got 'hiddenkey' credentials using 'My Credentials Plugin', try to
     authenticate using 'My Authenticator Plugin'
-    
+
   - Failed to authenticate 'hiddenkey' using 'My Authenticator Plugin', try
     'My Authenticator Plugin 2'
 
@@ -309,16 +324,16 @@
 ===================
 
 As a component that provides IAuthentication2, a PAU lets you lookup a
-principal with a principal ID. The PAU looks up a principal by delegating to 
+principal with a principal ID. The PAU looks up a principal by delegating to
 its authenticators. In out example, none of the authenticators implement this
 search capability, so when we look for a principal:
 
   >>> print pau.getPrincipal('bob')
   None
-  
+
   >>> print pau.getPrincipal('white')
   None
-  
+
   >>> print pau.getPrincipal('black')
   None
 
@@ -342,13 +357,13 @@
   ...         if id is not None:
   ...             return self.infos[id]
   ...
-  ...     def createAuthenticatedPrincipal(self, info, request):
+  ...     def createAuthenticatedPrincipal_XXX(self, info, request):
   ...         principal = principalfolder.Principal(info.id)
   ...         notify(interfaces.AuthenticatedPrincipalCreated(
   ...             principal, info, request))
   ...         return principal
   ...
-  ...     def createFoundPrincipal(self, info):
+  ...     def createFoundPrincipal_XXX(self, info):
   ...         principal = principalfolder.Principal(info.id)
   ...         notify(interfaces.FoundPrincipalCreated(principal, info))
   ...         return principal
@@ -364,7 +379,7 @@
 are less typical.
 
 As with any plugin, we need to register it as a utility:
-  
+
   >>> searchable = SearchableAuthenticatorPlugin()
   >>> provideUtility(searchable, name='Searchable Authentication Plugin')
 
@@ -403,11 +418,11 @@
   True
   >>> event.info
   PrincipalInfo('white')
-  
+
 As we have seen with authenticated principals, it is common to subscribe to
 principal created events to add information to the newly created principal.
 In this case, we need to subscribe to IFoundPrincipalCreated events:
-  
+
   >>> subscribe([interfaces.IFoundPrincipalCreated], None, add_info)
 
 Now when a principal is created as a result of a search, it's title and
@@ -471,10 +486,10 @@
 functionality is driven by the following use case:
 
   - A user attempts to perform an operation he is not authorized to perform.
-  
+
   - A handler responds to the unauthorized error by calling IAuthentication2
     'unauthorized'.
-    
+
   - The authentication component (in our case, a PAU) issues a challenge to
     the user to collect new credentials (typically in the form of logging in
     as a new user).
@@ -482,7 +497,7 @@
 The PAU handles the credentials challenge by delegating to its credentials
 plugins.
 
-Currently, the PAU is configured with the credentials plugins that don't 
+Currently, the PAU is configured with the credentials plugins that don't
 perform any action when asked to challenge (see above the 'challenge' methods).
 
 To illustrate challenges, we'll subclass an existing credentials plugin and

Modified: Zope3/trunk/src/zope/app/authentication/authentication.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/authentication.py	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/authentication.py	2005-03-29 22:07:44 UTC (rev 29722)
@@ -59,8 +59,8 @@
                 info = authplugin.authenticateCredentials(credentials)
                 if info is None:
                     continue
-                principal = authplugin.createAuthenticatedPrincipal(
-                    info, request)
+                principal = component.getMultiAdapter((info, request),
+                    interfaces.IAuthenticatedPrincipalFactory)()
                 principal.id = self.prefix + info.id
                 return principal
         return None
@@ -78,7 +78,7 @@
             info = authplugin.principalInfo(id)
             if info is None:
                 continue
-            principal = authplugin.createFoundPrincipal(info=info)
+            principal = interfaces.IFoundPrincipalFactory(info)()
             principal.id = self.prefix + info.id
             return principal
         next = queryNextUtility(self, IAuthentication2)

Modified: Zope3/trunk/src/zope/app/authentication/groupfolder.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/groupfolder.py	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/groupfolder.py	2005-03-29 22:07:44 UTC (rev 29722)
@@ -171,14 +171,6 @@
                 return principalfolder.PrincipalInfo(id, info.title,
                                                      info.description)
 
-    def createAuthenticatedPrincipal(self, info, request):
-        return component.getMultiAdapter((info, request),
-            interfaces.IAuthenticatedPrincipalFactory)()
-
-    def createFoundPrincipal(self, info):
-        return interfaces.IFoundPrincipalFactory(info)()
-
-
 class GroupCycle(Exception):
     """There is a cyclic relationship among groups
     """

Modified: Zope3/trunk/src/zope/app/authentication/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/interfaces.py	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/interfaces.py	2005-03-29 22:07:44 UTC (rev 29722)
@@ -102,25 +102,6 @@
         If the plugin cannot find information for the id, returns None.
         """
 
-    def createAuthenticatedPrincipal(info, request):
-        """Creates a principal authenticated against a request.
-
-        `info` provides IPrincipalInfo and is used create a principal.
-
-        If a principal is created, an AuthenticatedPrincipalCreated event is
-        published and the principal is returned. If no principal is created,
-        returns None.
-        """
-
-    def createFoundPrincipal(info):
-        """Creates a principal with info from a search operation.
-
-        `info` provides IPrincipalInfo and is to create the principal.
-
-        If a principal is created, a FoundPrincipalCreated is published and
-        the principal is returned.  If no principal is created, returns None.
-        """
-
 class IPrincipalInfo(zope.interface.Interface):
     """Minimal information about a principal."""
 

Modified: Zope3/trunk/src/zope/app/authentication/principalfolder.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/principalfolder.py	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/principalfolder.py	2005-03-29 22:07:44 UTC (rev 29722)
@@ -127,9 +127,9 @@
 
 class PrincipalInfo:
     """A basic implementation of interfaces.IPrincipalInfo.
-    
+
     A principal info is created with id, title, and description:
-      
+
       >>> info = PrincipalInfo('foo', 'Foo', 'An over-used term.')
       >>> info
       PrincipalInfo('foo')
@@ -142,7 +142,7 @@
 
     """
     interface.implements(interfaces.IPrincipalInfo)
-    
+
     def __init__(self, id, title, description):
         self.id = id
         self.title = title
@@ -151,10 +151,10 @@
     def __repr__(self):
         return 'PrincipalInfo(%r)' % self.id
 
-    
+
 class PrincipalFolder(BTreeContainer):
     """A Persistent Principal Folder and Authentication plugin.
-    
+
     See principalfolder.txt for details.
     """
 
@@ -211,7 +211,7 @@
         if principal.password != credentials['password']:
             return None
         return PrincipalInfo(
-            id=self.prefix + id, 
+            id=self.prefix + id,
             title=principal.title,
             description=principal.description)
 
@@ -239,14 +239,7 @@
                     yield self.prefix + value.__name__
                 i += 1
 
-    def createAuthenticatedPrincipal(self, info, request):
-        return component.getMultiAdapter((info, request), 
-            interfaces.IAuthenticatedPrincipalFactory)()
 
-    def createFoundPrincipal(self, info):
-        return interfaces.IFoundPrincipalFactory(info)()
-
-
 class Principal:
     """A group-aware implementation of zope.security.interfaces.IPrincipal.
 
@@ -257,7 +250,7 @@
       Principal(1)
       >>> p.id
       1
-    
+
     title and description may also be provided:
 
       >>> p = Principal('george', 'George', 'A site member.')
@@ -269,10 +262,10 @@
       'George'
       >>> p.description
       'A site member.'
-     
+
     """
     interface.implements(IGroupAwarePrincipal)
-    
+
     def __init__(self, id, title=u'', description=u''):
         self.id = id
         self.title = title
@@ -285,29 +278,29 @@
 
 class AuthenticatedPrincipalFactory:
     """Creates 'authenticated' principals.
-    
+
     An authenticated principal is created as a result of an authentication
     operation.
-    
+
     To use the factory, create it with the info (interfaces.IPrincipalInfo) of
     the principal to create and a request:
-    
+
       >>> info = PrincipalInfo('mary', 'Mary', 'The site admin.')
       >>> from zope.publisher.browser import TestRequest
       >>> request = TestRequest()
       >>> factory = AuthenticatedPrincipalFactory(info, request)
       >>> principal = factory()
-  
+
     The factory uses the info to create a principal with the same ID, title,
     and description:
- 
+
       >>> principal.id
       'mary'
       >>> principal.title
       'Mary'
       >>> principal.description
       'The site admin.'
-      
+
     It also fires an AuthenticatedPrincipalCreatedEvent:
 
       >>> from zope.app.event.tests.placelesssetup import getEvents
@@ -318,7 +311,7 @@
       PrincipalInfo('mary')
       >>> event.request is request
       True
-      
+
     Listeners can subscribe to this event to perform additional operations
     when the authenticated principal is created.
 
@@ -328,7 +321,7 @@
     component.adapts(interfaces.IPrincipalInfo, IBrowserRequest)
 
     interface.implements(interfaces.IAuthenticatedPrincipalFactory)
-    
+
     def __init__(self, info, request):
         self.info = info
         self.request = request
@@ -339,30 +332,30 @@
         notify(interfaces.AuthenticatedPrincipalCreated(
             principal, self.info, self.request))
         return principal
-        
 
+
 class FoundPrincipalFactory:
     """Creates 'found' principals.
-    
+
     A 'found' principal is created as a result of a principal lookup.
-    
+
     To use the factory, create it with the info (interfaces.IPrincipalInfo) of
     the principal to create:
-    
+
       >>> info = PrincipalInfo('sam', 'Sam', 'A site user.')
       >>> factory = FoundPrincipalFactory(info)
       >>> principal = factory()
-  
+
     The factory uses the info to create a principal with the same ID, title,
     and description:
- 
+
       >>> principal.id
       'sam'
       >>> principal.title
       'Sam'
       >>> principal.description
       'A site user.'
-      
+
     It also fires a FoundPrincipalCreatedEvent:
 
       >>> from zope.app.event.tests.placelesssetup import getEvents
@@ -371,17 +364,17 @@
       True
       >>> event.info
       PrincipalInfo('sam')
-      
+
     Listeners can subscribe to this event to perform additional operations
     when the 'found' principal is created.
-    
+
     For information on how factories are used in the authentication process,
     see README.txt.
-    """    
+    """
     component.adapts(interfaces.IPrincipalInfo)
 
     interface.implements(interfaces.IFoundPrincipalFactory)
-    
+
     def __init__(self, info):
         self.info = info
 

Modified: Zope3/trunk/src/zope/app/authentication/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/authentication/tests.py	2005-03-29 20:07:16 UTC (rev 29721)
+++ Zope3/trunk/src/zope/app/authentication/tests.py	2005-03-29 22:07:44 UTC (rev 29722)
@@ -21,7 +21,7 @@
 
 from zope.testing import doctest
 from zope.interface import implements
-from zope.component import provideUtility
+from zope.component import provideUtility, provideAdapter
 from zope.publisher.interfaces import IRequest
 from zope.publisher.tests.httprequest import TestRequest
 
@@ -73,6 +73,7 @@
                              setUp=siteSetUp,
                              tearDown=siteTearDown,
                              globs={'provideUtility': provideUtility,
+                                    'provideAdapter': provideAdapter,
                                     'getEvents': getEvents,
                                     'clearEvents': clearEvents,
                                     'subscribe': ztapi.subscribe,



More information about the Zope3-Checkins mailing list