[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