[Zope-CVS] CVS: Products/PluggableAuthService - PluggableAuthService.py:1.32 UserPropertySheet.py:1.4 __init__.py:1.7 utils.py:1.7

Sidnei da Silva sidnei at enfoldsystems.com
Wed Aug 17 16:53:44 EDT 2005


Update of /cvs-repository/Products/PluggableAuthService
In directory cvs.zope.org:/tmp/cvs-serv13697

Modified Files:
	PluggableAuthService.py UserPropertySheet.py __init__.py 
	utils.py 
Log Message:

Merge changes from sidnei-challenge-protocol-chooser:

    - Added two new interfaces, IChallengeProtocolChooser and
      IRequestTypeSniffer. Those are used to select the 'authorization
      protocol' or 'challenger protocol' to be used for challenging
      according to the incoming request type.

    - Fixed a couple more places where Zope 2-style __implements__
      where being used to standardize on using classImplements.

    - Fixed fallback implementations of providedBy and
      implementedBy to always return a tuple.

    - Make sure challenge doesn't break if existing instances of the
      PluginRegistry don't yet have IChallengeProtocolChooser as a
      registered interface. (Would be nice to have some sort of
      migration for the PluginRegistry between PAS releases)

    - Don't assume that just because zope.interface can be imported
      that Five is present.


=== Products/PluggableAuthService/PluggableAuthService.py 1.31 => 1.32 ===
--- Products/PluggableAuthService/PluggableAuthService.py:1.31	Fri May 27 15:10:45 2005
+++ Products/PluggableAuthService/PluggableAuthService.py	Wed Aug 17 16:53:13 2005
@@ -65,13 +65,15 @@
 from interfaces.plugins import IGroupEnumerationPlugin
 from interfaces.plugins import IRoleEnumerationPlugin
 from interfaces.plugins import IRoleAssignerPlugin
+from interfaces.plugins import IChallengeProtocolChooser
+from interfaces.plugins import IRequestTypeSniffer
 
 from permissions import SearchPrincipals
 
 from PropertiedUser import PropertiedUser
 from utils import _wwwdir
 from utils import createViewName
-
+from utils import classImplements
 
 security = ModuleSecurityInfo(
     'Products.PluggableAuthService.PluggableAuthService' )
@@ -95,8 +97,6 @@
 
 class DumbHTTPExtractor( Implicit ):
 
-    __implements__ = ( ILoginPasswordHostExtractionPlugin, )
-
     security = ClassSecurityInfo()
 
     security.declarePrivate( 'extractCredentials' )
@@ -121,13 +121,15 @@
 
         return creds
 
+classImplements( DumbHTTPExtractor
+               , ILoginPasswordHostExtractionPlugin
+               )
+
 InitializeClass( DumbHTTPExtractor )
 
 
 class EmergencyUserAuthenticator( Implicit ):
 
-    __implements__ = ( IAuthenticationPlugin, )
-
     security = ClassSecurityInfo()
 
     security.declarePrivate( 'authenticateCredentials' )
@@ -149,6 +151,10 @@
 
         return (None, None)
 
+classImplements( EmergencyUserAuthenticator
+               , IAuthenticationPlugin
+               )
+
 InitializeClass( EmergencyUserAuthenticator )
 
 
@@ -156,8 +162,6 @@
 
     """ All-singing, all-dancing user folder.
     """
-    __implements__ = ( IPluggableAuthService, )
-
     security = ClassSecurityInfo()
 
     meta_type = 'Pluggable Auth Service'
@@ -986,8 +990,26 @@
             resp._has_challenged = True
 
     def challenge(self, request, response):
-        # Go through all challenge plugins
         plugins = self._getOb('plugins')
+
+        # Find valid protocols for this request type
+        valid_protocols = []
+        choosers = []
+        try:
+            choosers = plugins.listPlugins( IChallengeProtocolChooser )
+        except KeyError:
+            # Work around the fact that old instances might not have
+            # IChallengeProtocolChooser registered with the
+            # PluginRegistry.
+            pass
+
+        for chooser_id, chooser in choosers:
+            choosen = chooser.chooseProtocols(request)
+            if choosen is None:
+                continue
+            valid_protocols.extend(choosen)
+
+        # Go through all challenge plugins
         challengers = plugins.listPlugins( IChallengePlugin )
 
         protocol = None
@@ -995,6 +1017,9 @@
         for challenger_id, challenger in challengers:
             challenger_protocol = getattr(challenger, 'protocol',
                                           challenger_id)
+            if valid_protocols and challenger_protocol not in valid_protocols:
+                # Skip invalid protocol for this request type.
+                continue
             if protocol is None or protocol == challenger_protocol:
                 if challenger.challenge(request, response):
                     protocol = challenger_protocol
@@ -1072,6 +1097,9 @@
             for resetter_id, resetter in cred_resetters:
                 resetter.resetCredentials(request, response)
 
+classImplements( PluggableAuthService
+               , IPluggableAuthService
+               )
 
 InitializeClass( PluggableAuthService )
 
@@ -1168,6 +1196,17 @@
     , 'role_assigner'
     , "Role Assigner plugins allow the Pluggable Auth Service to assign"
       " roles to principals."
+    )
+  , ( IChallengeProtocolChooser
+    , 'IChallengeProtocolChooser'
+    , 'challenge_protocol_chooser'
+    , "Challenge Protocol Chooser plugins decide what authorization"
+      "protocol to use for a given request type."
+    )
+  , ( IRequestTypeSniffer
+    , 'IRequestTypeSniffer'
+    , 'request_type_sniffer'
+    , "Request Type Sniffer plugins detect the type of an incoming request."
     )
   )
 


=== Products/PluggableAuthService/UserPropertySheet.py 1.3 => 1.4 ===
--- Products/PluggableAuthService/UserPropertySheet.py:1.3	Thu Aug 12 11:15:53 2004
+++ Products/PluggableAuthService/UserPropertySheet.py	Wed Aug 17 16:53:13 2005
@@ -34,9 +34,11 @@
 
 from DateTime.DateTime import DateTime
 
+from Products.PluggableAuthService.utils import classImplements
 from Products.PluggableAuthService.interfaces.propertysheets \
     import IPropertySheet
 
+
 def _guessSchema( kw ):
 
     schema = []
@@ -85,8 +87,6 @@
       guess the schema from the keyword args.
     """
 
-    __implements__ = ( IPropertySheet, )
-
     def __init__( self, id, schema=None, **kw ):
 
         self._id = id
@@ -173,3 +173,7 @@
         """ See IPropertySheet.
         """
         return [ ( x, self._properties.get( x ) ) for x in self.propertyIds() ]
+
+classImplements( UserPropertySheet
+               , IPropertySheet
+               )


=== Products/PluggableAuthService/__init__.py 1.6 => 1.7 ===
--- Products/PluggableAuthService/__init__.py:1.6	Thu Jan 27 14:00:22 2005
+++ Products/PluggableAuthService/__init__.py	Wed Aug 17 16:53:13 2005
@@ -43,6 +43,8 @@
 from plugins import SearchPrincipalsPlugin as SPP
 from plugins import RecursiveGroupsPlugin as RGP
 from plugins import DynamicGroupsPlugin as DGP
+from plugins import ChallengeProtocolChooser as CPC
+from plugins import RequestTypeSniffer as RTS
 
 registerMultiPlugin(HBAH.HTTPBasicAuthHelper.meta_type)
 registerMultiPlugin(IAH.InlineAuthHelper.meta_type)
@@ -58,6 +60,8 @@
 registerMultiPlugin(SPP.SearchPrincipalsPlugin.meta_type)
 registerMultiPlugin(RGP.RecursiveGroupsPlugin.meta_type)
 registerMultiPlugin(DGP.DynamicGroupsPlugin.meta_type)
+registerMultiPlugin(CPC.ChallengeProtocolChooser.meta_type)
+registerMultiPlugin(RTS.RequestTypeSniffer.meta_type)
 
 # monkey patch Zope to cause zmi logout to be PAS-aware
 from App.Management import Navigation
@@ -224,4 +228,22 @@
                             DGP.addDynamicGroupsPlugin, )
                          , visibility=None
                          , icon='plugins/www/DynamicGroupsPlugin.png'
+                         )
+
+    context.registerClass( CPC.ChallengeProtocolChooser
+                         , permission=ManageUsers
+                         , constructors=(
+                            CPC.manage_addChallengeProtocolChooserForm,
+                            CPC.addChallengeProtocolChooserPlugin, )
+                         , visibility=None
+                         , icon='plugins/www/DelegatingMultiPlugin.png'
+                         )
+
+    context.registerClass( RTS.RequestTypeSniffer
+                         , permission=ManageUsers
+                         , constructors=(
+                            RTS.manage_addRequestTypeSnifferForm,
+                            RTS.addRequestTypeSnifferPlugin, )
+                         , visibility=None
+                         , icon='plugins/www/DelegatingMultiPlugin.png'
                          )


=== Products/PluggableAuthService/utils.py 1.6 => 1.7 ===
--- Products/PluggableAuthService/utils.py:1.6	Wed Jul  6 14:47:07 2005
+++ Products/PluggableAuthService/utils.py	Wed Aug 17 16:53:13 2005
@@ -14,20 +14,36 @@
 ##############################################################################
 import os
 import unittest
+from types import TupleType, ListType
 
 from Globals import package_home
 
+def tuplize(value):
+    if isinstance(value, TupleType):
+        return value
+    if isinstance(value, ListType):
+        return tuple(value)
+    return (value,)
+
 try:
     from zope.interface import providedBy
 except ImportError:
     def providedBy(obj):
-        return obj.__implements__
+        return tuplize(obj.__implements__)
 
 try:
     from zope.interface import implementedBy
 except ImportError:
     def implementedBy(klass):
-        return klass.__implements__
+        return tuplize(klass.__implements__)
+
+try:
+    from Products.Five.bridge import fromZ2Interface
+except ImportError:
+    def fromZ2Interface(i):
+        # Raise ValueError to work around a cornerish case where
+        # zope.interface is available but Five is not.
+        raise ValueError, i
 
 try:
     from zope import interface
@@ -40,7 +56,6 @@
 
 else:
     def directlyProvides(obj, *interfaces):
-        from Products.Five.bridge import fromZ2Interface
         # convert any Zope 2 interfaces to Zope 3 using fromZ2Interface
         normalized_interfaces = []
         for i in interfaces:
@@ -52,7 +67,6 @@
         return interface.directlyProvides(obj, *normalized_interfaces)
 
     def classImplements(class_, *interfaces):
-        from Products.Five.bridge import fromZ2Interface
         # convert any Zope 2 interfaces to Zope 3 using fromZ2Interface
         normalized_interfaces = []
         for i in interfaces:



More information about the Zope-CVS mailing list