[Checkins] SVN: Sandbox/ulif/grok-adminui-with-principals/src/grok/ A PAU with fallback-mechanism.

Uli Fouquet uli at gnufix.de
Tue Aug 21 14:16:18 EDT 2007


Log message for revision 79090:
  A PAU with fallback-mechanism.

Changed:
  U   Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/__init__.py
  A   Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/auth.py
  U   Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/view.py
  U   Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/loginlogout.py
  U   Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/principalmanager.py

-=-
Modified: Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/__init__.py
===================================================================
--- Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/__init__.py	2007-08-21 17:52:03 UTC (rev 79089)
+++ Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/__init__.py	2007-08-21 18:16:18 UTC (rev 79090)
@@ -20,87 +20,47 @@
 
 from zope.component import adapter, provideHandler
 from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent
+from zope.app.authentication import PluggableAuthentication
+from zope.app.authentication.interfaces import IAuthenticatorPlugin
+from zope.app.security.interfaces import IAuthentication
 
+from auth import GrokAuthenticator
+
 AUTH_FOLDERNAME=u'authentication'
 USERFOLDER_NAME=u'Users'
 USERFOLDER_PREFIX=u'grokadmin'
 
-def getPrincipalCredentialsFromZCML():
-    """Read all principals' attributes from site.zcml.
-    """
-    import xml.sax
-    from zope.app.appsetup.appsetup import getConfigSource
 
-    class SAXPrincipalFinder(xml.sax.ContentHandler):
-        """Parse an XML file and get attributes of ``principal`` tags.
-
-        The principal tags of site.xml contain the credentials of
-        principals as attributes. The attributes usually are 'id',
-        'login', 'password', 'title' and other more. And usually only
-        one pricipal is defined: the manager.
-        """
-        result = []
-
-        def startElement(self, name, attrs):
-            if name != 'principal':
-                return
-            self.result.append(dict(attrs.copy()))
-
-    site_zcml_file = getConfigSource()
-    principal_finder = SAXPrincipalFinder()
-    xml.sax.parse(site_zcml_file, principal_finder)
-    return principal_finder.result
-
-
 def setupSessionAuthentication(root_folder=None,
-                               principal_credentials=[{u'id': u'zope.manager',
-                                                      u'login': u'grok',
-                                                      u'password': u'grok',
-                                                      u'title': u'Manager'
-                                                      }],
                                auth_foldername=AUTH_FOLDERNAME,
-                               userfolder_name=USERFOLDER_NAME,
-                               userfolder_prefix=USERFOLDER_PREFIX
-                               ):
+                               userfolder_name = USERFOLDER_NAME,
+                               userfolder_prefix=USERFOLDER_PREFIX):
     """Add session authentication PAU to root_folder.
 
     Add a PluggableAuthentication in site manager of
     root_folder. ``auth_foldername`` gives the name of the PAU to
     install, userfolder_prefix the prefix of the authenticator plugin
-    (a simple ``PrincipalFolder``), which will be created in the PAU
-    and gets name ``userfolder_name``. ``principal_credentials`` is a
-    list of dicts with, well, principal_credentials. The keys ``id``,
-    ``login``, ``password`` and ``title`` are required for each
-    element of this list.
+    (a ``GrokAuthenticator``), which will be created in the PAU
+    and gets name ``userfolder_name``.
     """
-    from zope.component import getUtilitiesFor
-    from zope.security.proxy import removeSecurityProxy
-    from zope.app.security.interfaces import IAuthentication
-    from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
-    from zope.app.securitypolicy.interfaces import IRole
-    from zope.app.authentication import PluggableAuthentication
-    from zope.app.authentication.interfaces import IAuthenticatorPlugin
-    from zope.app.authentication.principalfolder import PrincipalFolder
-    from zope.app.authentication.principalfolder import InternalPrincipal
-
     sm = root_folder.getSiteManager()
     if auth_foldername in sm.keys():
-        # There is already a folder of this name.
-        return
+        userfolder = sm[auth_foldername]
+        if isinstance(userfolder[userfolder_name], GrokAuthenticator):
+            # Correct PAU already installed.
+            return
+        # Remove old PAU
+        site_manager.unregisterUtility(name=u'', provided=IAuthentication)
+        site_manager.unregisterUtility(name=USERFOLDER_NAME,
+                                       provided=IAuthenticatorPlugin)
+        try:
+            del site_manager[auth_foldername]
+        except:
+            pass
 
     pau = PluggableAuthentication()
-    users = PrincipalFolder(userfolder_prefix)
+    users = GrokAuthenticator(userfolder_prefix)
 
-    # Add users into principals folder to enable login...
-    for user in principal_credentials:
-        # XXX make sure, the keys exist...
-        user['id'] = user['id'].rsplit('.',1)[-1]
-        user_title = user['title']
-        principal = InternalPrincipal(user['login'],
-                                      user['password'],
-                                      user['title'])
-        users[user['id']] = principal
-
     # Configure the PAU...
     pau.authenticatorPlugins = (userfolder_name,)
     pau.credentialsPlugins = ("No Challenge if Authenticated",
@@ -115,18 +75,7 @@
     sm.registerUtility(pau, IAuthentication)
     sm.registerUtility(users, IAuthenticatorPlugin, name=userfolder_name)
 
-    # Add manager roles to new users...
-    # XXX the real roles could be obtained from site.zcml.
-    role_ids = [name for name, util in getUtilitiesFor(IRole, root_folder)]
-    user_ids = [users.prefix + p['id'] for p in principal_credentials]
-    role_manager = IPrincipalRoleManager(root_folder)
-    role_manager = removeSecurityProxy(role_manager)
-    for role in role_ids:
-        for user_id in user_ids:
-            role_manager.assignRoleToPrincipal(role,user_id)
 
-
-
 # If a new database is created, initialize a session based
 # authentication.
 #
@@ -137,11 +86,8 @@
     from zope.app.appsetup.bootstrap import getInformationFromEvent
     
     db, connection, root, root_folder = getInformationFromEvent(event)
-    principal_credentials = getPrincipalCredentialsFromZCML()
-    setupSessionAuthentication(root_folder = root_folder,
-                               principal_credentials = principal_credentials)
+    setupSessionAuthentication(root_folder = root_folder)
 
-
 # ...then install the event handler:
 provideHandler(adminSetup)
 

Added: Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/auth.py
===================================================================
--- Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/auth.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/auth.py	2007-08-21 18:16:18 UTC (rev 79090)
@@ -0,0 +1,63 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from zope.app.authentication.principalfolder import PrincipalFolder
+from zope.app.authentication.principalfolder import PrincipalInfo
+from zope.app.security.principalregistry import principalRegistry
+
+class GrokAuthenticator(PrincipalFolder):
+    """A PrincipalFolder with fallback that asks also the root authentication.
+
+    This special principal folder can be used as an authenticator,
+    that is able to also authenticate against the principals defined
+    in site.zcml.
+    """
+
+    def authenticateCredentials(self, credentials):
+        """Return principal info if credentials can be authenticated
+        """
+        if not isinstance(credentials, dict):
+            return None
+        if not ('login' in credentials and 'password' in credentials):
+            return None
+        # We shadow principals defined in site.zcml.
+        result = PrincipalFolder.authenticateCredentials(self, credentials)
+        if result is not None:
+            return result
+
+        principal = None
+        login, password = credentials['login'], credentials['password']
+        try:
+            principal = principalRegistry.getPrincipalByLogin(login)
+        except KeyError:
+            return
+        if principal and principal.validate(password):
+            return PrincipalInfo(principal.id,
+                                 principal.getLogin(),
+                                 principal.title,
+                                 principal.description)
+        return
+        
+
+    def principalInfo(self, id):
+        result = PrincipalFolder.principalInfo(self, id)
+        if result is not None:
+            return result
+        principal = principalRegistry.getPrincipal(id)
+        return PrincipalInfo(principal.id,
+                             principal.getLogin(),
+                             principal.title,
+                             principal.description)
+        return result
+

Modified: Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/view.py
===================================================================
--- Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/view.py	2007-08-21 17:52:03 UTC (rev 79089)
+++ Sandbox/ulif/grok-adminui-with-principals/src/grok/admin/view.py	2007-08-21 18:16:18 UTC (rev 79090)
@@ -622,17 +622,17 @@
                 role_manager.unsetRoleForPrincipal(role, id)
         self.msg=u'Principal `%s` successfully updated.' % (title,)
 
-
     def update(self, id=None, login=None, title=None, description=None,
                passwd=None, roles=[], addprincipal=None, delprincipal=None,
                setpassword=None, update=None):
+        self.roles = []
+        self.principals = []
+        self.msg = ""
         self.userfolder = self.getUserFolder()
         if self.userfolder is None:
-            self.msg = ("This usermanagement screen is disabled because no "
-                        "working pluggable authentication utility (PAU) with "
-                        "a pluggable authenticator could be found. "
-                        "Please register one in the site manager of your "
-                        "Zope root to enable this screen again.")
+            self.msg = ("This usermanagement screen is disabled, because no "
+                        "working pluggable authentication utility (PAU) could "
+                        "be found.")
             # We need a PAU to work.
             return
         if isinstance(roles, basestring):

Modified: Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/loginlogout.py
===================================================================
--- Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/loginlogout.py	2007-08-21 17:52:03 UTC (rev 79089)
+++ Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/loginlogout.py	2007-08-21 18:16:18 UTC (rev 79090)
@@ -22,15 +22,9 @@
 the ftesting setup is set up. We therefore set up the PAU manually.
 
   >>> root = getRootFolder()
-  >>> root is not None
-  True
-
   >>> import grok.admin
-  >>> principal_credentials = grok.admin.getPrincipalCredentialsFromZCML()
-  >>> principal_credentials
-  [{u'login': u'mgr', u'password': u'mgrpw', u'id': u'zope.mgr', u'title': u'Manager'}]
+  >>> grok.admin.setupSessionAuthentication(root_folder = root)
 
-  >>> grok.admin.setupSessionAuthentication(root_folder = root, principal_credentials = principal_credentials)
 
 We should get a login page if trying to get something unauthenticated.
 

Modified: Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/principalmanager.py
===================================================================
--- Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/principalmanager.py	2007-08-21 17:52:03 UTC (rev 79089)
+++ Sandbox/ulif/grok-adminui-with-principals/src/grok/ftests/admin/principalmanager.py	2007-08-21 18:16:18 UTC (rev 79090)
@@ -39,22 +39,16 @@
   >>> print browser.contents
   <html xmlns="http://www.w3.org/1999/xhtml">
   ...
-  ...This usermanagement screen is disabled because no working...
-  ...pluggable authentication utility (PAU) with a pluggable...
-  ...authenticator could be found. Please register one in the...
-  ...site manager of your Zope root to enable this screen again...
+  ...This usermanagement screen is disabled, because no working...
+  ...pluggable authentication utility (PAU) could be found...
   ...
 
 So we have to set up our own PAU first:
 
   >>> root = getRootFolder()
   >>> import grok.admin
-  >>> principal_credentials = grok.admin.getPrincipalCredentialsFromZCML()
-  >>> principal_credentials
-  [{u'login': u'mgr', u'password': u'mgrpw', u'id': u'zope.mgr', u'title': u'Manager'}]
+  >>> grok.admin.setupSessionAuthentication(root_folder = root)
 
-  >>> grok.admin.setupSessionAuthentication(root_folder = root, principal_credentials = principal_credentials)
-
 We should get a login page if trying to get something unauthenticated.
 
   >>> from zope.testbrowser.testing import Browser



More information about the Checkins mailing list