[Checkins] SVN: zope.app.authentication/trunk/s Merged branch to use zope.pluggableauth.
Souheil CHELFOUH
souheil at chelfouh.com
Sat Feb 6 06:16:45 EST 2010
Log message for revision 108827:
Merged branch to use zope.pluggableauth.
Backward compatibility is assured by imports.
Tests have been slightly mofidied to take in account the new physical location of some moves classes.
Changed:
U zope.app.authentication/trunk/setup.py
U zope.app.authentication/trunk/src/zope/app/authentication/README.txt
U zope.app.authentication/trunk/src/zope/app/authentication/__init__.py
U zope.app.authentication/trunk/src/zope/app/authentication/authentication.py
U zope.app.authentication/trunk/src/zope/app/authentication/browser/group_searching_with_empty_string.txt
U zope.app.authentication/trunk/src/zope/app/authentication/browser/groupfolder.txt
U zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.txt
U zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/browser/schemasearch.py
U zope.app.authentication/trunk/src/zope/app/authentication/browser/session.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/browser/special-groups.txt
U zope.app.authentication/trunk/src/zope/app/authentication/browser/tests.py
U zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/ftesting.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.py
U zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/generic.py
U zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.py
U zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py
U zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py
U zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/session.py
U zope.app.authentication/trunk/src/zope/app/authentication/session.zcml
U zope.app.authentication/trunk/src/zope/app/authentication/tests.py
U zope.app.authentication/trunk/src/zope/app/authentication/vocabulary.py
-=-
Modified: zope.app.authentication/trunk/setup.py
===================================================================
--- zope.app.authentication/trunk/setup.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/setup.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -27,10 +27,11 @@
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
setup(name='zope.app.authentication',
- version = '3.6.3dev',
+ version = '3.7.0dev',
author='Zope Corporation and Contributors',
author_email='zope-dev at zope.org',
- description='Pluggable Authentication Utility',
+ description=('Principals and groups management for '
+ 'the pluggable authentication utility'),
long_description=(
read('README.txt')
+ '\n\n' +
@@ -60,34 +61,43 @@
keywords='zope3 authentication pluggable principal group',
packages=find_packages('src'),
package_dir = {'': 'src'},
- extras_require=dict(test=['zope.app.testing',
- 'zope.app.securitypolicy',
- 'zope.app.zcmlfiles',
- 'zope.securitypolicy',
- 'zope.testbrowser',
- 'zope.login',]),
+ extras_require=dict(test=[
+ 'zope.app.testing',
+ 'zope.app.securitypolicy',
+ 'zope.app.zcmlfiles',
+ 'zope.securitypolicy',
+ 'zope.testbrowser',
+ 'zope.publisher',
+ 'zope.testing',
+ 'zope.session',
+ 'zope.formlib',
+ 'zope.publisher>=3.12',
+ 'zope.site',
+ 'zope.login',]),
namespace_packages=['zope', 'zope.app'],
- install_requires=['setuptools',
- 'zope.app.component',
- 'zope.app.container',
- 'zope.app.form',
- 'zope.authentication',
- 'zope.dublincore',
- 'zope.event',
- 'zope.exceptions',
- 'zope.i18n',
- 'zope.i18nmessageid',
- 'zope.interface',
- 'zope.location',
- 'zope.password>=3.5.1',
- 'zope.publisher>=3.12',
- 'zope.schema',
- 'zope.security',
- 'zope.session',
- 'zope.site',
- 'zope.traversing',
- 'ZODB3',
- ],
+ install_requires=[
+ 'ZODB3',
+ 'setuptools',
+ 'zope.app.form',
+ 'zope.app.container',
+ 'zope.app.component',
+ 'zope.authentication',
+ 'zope.component',
+ 'zope.container',
+ 'zope.dublincore',
+ 'zope.event',
+ 'zope.exceptions',
+ 'zope.formlib',
+ 'zope.i18n',
+ 'zope.i18nmessageid',
+ 'zope.interface',
+ 'zope.location',
+ 'zope.password>=3.5.1',
+ 'zope.pluggableauth',
+ 'zope.schema',
+ 'zope.security',
+ 'zope.traversing',
+ ],
include_package_data = True,
zip_safe = False,
)
Modified: zope.app.authentication/trunk/src/zope/app/authentication/README.txt
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/README.txt 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/README.txt 2010-02-06 11:16:44 UTC (rev 108827)
@@ -817,6 +817,6 @@
>>> queriable = queriables[0][1]
>>> queriable.__parent__ # doctest: +ELLIPSIS
- <zope.app.authentication.authentication.PluggableAuthentication object ...>
+ <zope.pluggableauth.authentication.PluggableAuthentication object ...>
>>> queriable.__parent__ is pau
True
Modified: zope.app.authentication/trunk/src/zope/app/authentication/__init__.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/__init__.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/__init__.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -17,4 +17,4 @@
"""
import interfaces
-from zope.app.authentication.authentication import PluggableAuthentication
+from zope.pluggableauth.authentication import PluggableAuthentication
Modified: zope.app.authentication/trunk/src/zope/app/authentication/authentication.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/authentication.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/authentication.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -15,131 +15,18 @@
$Id$
"""
+
import zope.interface
from zope import component
-from zope.schema.interfaces import ISourceQueriables
from zope.location.interfaces import ILocation
-from zope.site.next import queryNextUtility
-
-from zope.authentication.interfaces import IAuthentication, PrincipalLookupError
-import zope.container.btree
-
from zope.app.authentication import interfaces
-class PluggableAuthentication(zope.container.btree.BTreeContainer):
+### BBB using zope.pluggableauth
+from zope.pluggableauth import PluggableAuthentication
+from zope.pluggableauth.interfaces import (
+ IQueriableAuthenticator, IPluggableAuthentication)
- zope.interface.implements(
- IAuthentication,
- interfaces.IPluggableAuthentication,
- ISourceQueriables)
- authenticatorPlugins = ()
- credentialsPlugins = ()
-
- def __init__(self, prefix=''):
- super(PluggableAuthentication, self).__init__()
- self.prefix = prefix
-
- def _plugins(self, names, interface):
- for name in names:
- plugin = self.get(name)
- if not interface.providedBy(plugin):
- plugin = component.queryUtility(interface, name, context=self)
- if plugin is not None:
- yield name, plugin
-
- def getAuthenticatorPlugins(self):
- return self._plugins(
- self.authenticatorPlugins, interfaces.IAuthenticatorPlugin)
-
- def getCredentialsPlugins(self):
- return self._plugins(
- self.credentialsPlugins, interfaces.ICredentialsPlugin)
-
- def authenticate(self, request):
- authenticatorPlugins = [p for n, p in self.getAuthenticatorPlugins()]
- for name, credplugin in self.getCredentialsPlugins():
- credentials = credplugin.extractCredentials(request)
- for authplugin in authenticatorPlugins:
- if authplugin is None:
- continue
- info = authplugin.authenticateCredentials(credentials)
- if info is None:
- continue
- info.credentialsPlugin = credplugin
- info.authenticatorPlugin = authplugin
- principal = component.getMultiAdapter((info, request),
- interfaces.IAuthenticatedPrincipalFactory)(self)
- principal.id = self.prefix + info.id
- return principal
- return None
-
- def getPrincipal(self, id):
- if not id.startswith(self.prefix):
- next = queryNextUtility(self, IAuthentication)
- if next is None:
- raise PrincipalLookupError(id)
- return next.getPrincipal(id)
- id = id[len(self.prefix):]
- for name, authplugin in self.getAuthenticatorPlugins():
- info = authplugin.principalInfo(id)
- if info is None:
- continue
- info.credentialsPlugin = None
- info.authenticatorPlugin = authplugin
- principal = interfaces.IFoundPrincipalFactory(info)(self)
- principal.id = self.prefix + info.id
- return principal
- next = queryNextUtility(self, IAuthentication)
- if next is not None:
- return next.getPrincipal(self.prefix + id)
- raise PrincipalLookupError(id)
-
- def getQueriables(self):
- for name, authplugin in self.getAuthenticatorPlugins():
- queriable = component.queryMultiAdapter((authplugin, self),
- interfaces.IQueriableAuthenticator)
- if queriable is not None:
- yield name, queriable
-
- def unauthenticatedPrincipal(self):
- return None
-
- def unauthorized(self, id, request):
- challengeProtocol = None
-
- for name, credplugin in self.getCredentialsPlugins():
- protocol = getattr(credplugin, 'challengeProtocol', None)
- if challengeProtocol is None or protocol == challengeProtocol:
- if credplugin.challenge(request):
- if protocol is None:
- return
- elif challengeProtocol is None:
- challengeProtocol = protocol
-
- if challengeProtocol is None:
- next = queryNextUtility(self, IAuthentication)
- if next is not None:
- next.unauthorized(id, request)
-
- def logout(self, request):
- challengeProtocol = None
-
- for name, credplugin in self.getCredentialsPlugins():
- protocol = getattr(credplugin, 'challengeProtocol', None)
- if challengeProtocol is None or protocol == challengeProtocol:
- if credplugin.logout(request):
- if protocol is None:
- return
- elif challengeProtocol is None:
- challengeProtocol = protocol
-
- if challengeProtocol is None:
- next = queryNextUtility(self, IAuthentication)
- if next is not None:
- next.logout(request)
-
-
class QuerySchemaSearchAdapter(object):
"""Performs schema-based principal searches on behalf of a PAU.
@@ -149,12 +36,12 @@
"""
component.adapts(
interfaces.IQuerySchemaSearch,
- interfaces.IPluggableAuthentication)
+ IPluggableAuthentication)
zope.interface.implements(
- interfaces.IQueriableAuthenticator,
- interfaces.IQuerySchemaSearch,
- ILocation)
+ ILocation,
+ IQueriableAuthenticator,
+ interfaces.IQuerySchemaSearch)
def __init__(self, authplugin, pau):
if (ILocation.providedBy(authplugin) and
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/group_searching_with_empty_string.txt
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/group_searching_with_empty_string.txt 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/group_searching_with_empty_string.txt 2010-02-06 11:16:44 UTC (rev 108827)
@@ -8,9 +8,9 @@
... Authorization: Basic bWdyOm1ncnB3
... Content-Length: 98
... Content-Type: application/x-www-form-urlencoded
- ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication
+ ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication
...
- ... type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication&new_value=PAU""")
+ ... type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication&new_value=PAU""")
HTTP/1.1 303 See Other
...
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/groupfolder.txt
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/groupfolder.txt 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/groupfolder.txt 2010-02-06 11:16:44 UTC (rev 108827)
@@ -21,9 +21,9 @@
... Content-Length: 98
... Content-Type: application/x-www-form-urlencoded
... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs
- ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication
+ ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication
...
- ... type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication&new_value=PAU""")
+ ... type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication&new_value=PAU""")
HTTP/1.1 303 See Other
...
@@ -31,7 +31,7 @@
... GET /++etc++site/default/PAU/@@registration.html HTTP/1.1
... Authorization: Basic bWdyOm1ncnB3
... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs
- ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication
+ ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication
... """)
HTTP/1.1 200 OK
...
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.txt
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.txt 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.txt 2010-02-06 11:16:44 UTC (rev 108827)
@@ -26,9 +26,9 @@
... Content-Length: 98
... Content-Type: application/x-www-form-urlencoded
... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs
- ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication
+ ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication
...
- ... type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication&new_value=PAU""",
+ ... type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication&new_value=PAU""",
... handle_errors=False)
HTTP/1.1 303 See Other
...
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/principalfolder.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -1,6 +1,4 @@
-<configure
- xmlns="http://namespaces.zope.org/browser"
- >
+<configure xmlns="http://namespaces.zope.org/browser">
<addform
schema="..principalfolder.IInternalPrincipalContainer"
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/schemasearch.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/schemasearch.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/schemasearch.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -17,13 +17,13 @@
"""
__docformat__ = "reStructuredText"
+from zope.app.authentication.i18n import ZopeMessageFactory as _
+from zope.app.form.browser.interfaces import ISourceQueryView
+from zope.app.form.utility import setUpWidgets, getWidgetsData
+from zope.formlib.interfaces import IInputWidget
+from zope.i18n import translate
from zope.interface import implements
-from zope.i18n import translate
from zope.schema import getFieldsInOrder
-from zope.app.form.utility import setUpWidgets, getWidgetsData
-from zope.app.form.interfaces import IInputWidget
-from zope.app.form.browser.interfaces import ISourceQueryView
-from zope.app.authentication.i18n import ZopeMessageFactory as _
from zope.traversing.api import getName, getPath
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/session.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/session.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/session.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -4,7 +4,7 @@
<addMenuItem
title="Session Credentials Plugin"
- class="..session.SessionCredentialsPlugin"
+ class="zope.pluggableauth.plugins.session.SessionCredentialsPlugin"
permission="zope.ManageServices"
/>
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/special-groups.txt
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/special-groups.txt 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/special-groups.txt 2010-02-06 11:16:44 UTC (rev 108827)
@@ -24,9 +24,9 @@
... Content-Length: 98
... Content-Type: application/x-www-form-urlencoded
... Cookie: zope3_cs_6a553b3=-j7C3CdeW9sUK8BP5x97u2d9o242xMJDzJd8HCQ5AAi9xeFcGTFkAs
- ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication
+ ... Referer: http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication
...
- ... type_name=BrowserAdd__zope.app.authentication.authentication.PluggableAuthentication&new_value=PAU""")
+ ... type_name=BrowserAdd__zope.pluggableauth.authentication.PluggableAuthentication&new_value=PAU""")
HTTP/1.1 303 See Other
...
Modified: zope.app.authentication/trunk/src/zope/app/authentication/browser/tests.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/browser/tests.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/browser/tests.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -26,8 +26,8 @@
from zope.interface import directlyProvides
from zope.exceptions.interfaces import UserError
from zope.app.testing import functional
+from zope.pluggableauth.factories import Principal
from zope.app.authentication.principalfolder import PrincipalFolder
-from zope.app.authentication.principalfolder import Principal
from zope.app.authentication.principalfolder import IInternalPrincipal
from zope.app.authentication.testing import AppAuthenticationLayer
Modified: zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/configure.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -4,21 +4,21 @@
i18n_domain="zope"
>
- <class class=".PluggableAuthentication">
+ <class class="zope.pluggableauth.authentication.PluggableAuthentication">
<implements
interface="zope.annotation.interfaces.IAttributeAnnotatable"
/>
<require
permission="zope.ManageSite"
- interface=".interfaces.IPluggableAuthentication"
- set_schema=".interfaces.IPluggableAuthentication"
+ interface="zope.pluggableauth.interfaces.IPluggableAuthentication"
+ set_schema="zope.pluggableauth.interfaces.IPluggableAuthentication"
/>
</class>
<adapter
for=".interfaces.IQuerySchemaSearch
- .interfaces.IPluggableAuthentication"
- provides=".interfaces.IQueriableAuthenticator"
+ zope.pluggableauth.interfaces.IPluggableAuthentication"
+ provides="zope.pluggableauth.interfaces.IQueriableAuthenticator"
factory=".authentication.QuerySchemaSearchAdapter"
/>
@@ -34,8 +34,8 @@
<utility
name="No Challenge if Authenticated"
- factory=".generic.NoChallengeCredentialsPlugin"
- provides=".interfaces.ICredentialsPlugin"
+ factory="zope.pluggableauth.plugins.generic.NoChallengeCredentialsPlugin"
+ provides="zope.pluggableauth.interfaces.ICredentialsPlugin"
/>
<!-- Registering documentation with API doc -->
Modified: zope.app.authentication/trunk/src/zope/app/authentication/ftesting.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/ftesting.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/ftesting.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -29,7 +29,9 @@
<grantAll role="zope.Manager" />
- <include package="zope.app.securitypolicy.browser.tests" file="functional.zcml" />
+ <include
+ package="zope.app.securitypolicy.browser.tests"
+ file="functional.zcml" />
<!-- Principals -->
Modified: zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -15,51 +15,5 @@
"""
__docformat__ = 'restructuredtext'
-from zope.interface import implements
-from zope.publisher.interfaces.ftp import IFTPRequest
-
-from zope.app.authentication import interfaces
-
-class FTPCredentialsPlugin(object):
-
- implements(interfaces.ICredentialsPlugin)
-
- def extractCredentials(self, request):
- """Extracts the FTP credentials from a request.
-
- First we need to create a FTP request that contains some credentials.
- Note the path is a required in the envirnoment.
-
- >>> from zope.publisher.ftp import FTPRequest
- >>> from StringIO import StringIO
- >>> request = FTPRequest(StringIO(''),
- ... {'credentials': ('bob', '123'),
- ... 'path': '/a/b/c'})
-
- Now we create the plugin and get the credentials.
-
- >>> plugin = FTPCredentialsPlugin()
- >>> plugin.extractCredentials(request)
- {'login': u'bob', 'password': u'123'}
-
- This only works for FTPRequests.
-
- >>> from zope.publisher.base import TestRequest
- >>> print plugin.extractCredentials(TestRequest('/'))
- None
-
- """
- if not IFTPRequest.providedBy(request):
- return None
-
- if request._auth:
- login, password = request._auth
- return {'login': login.decode('utf-8'),
- 'password': password.decode('utf-8')}
- return None
-
- def challenge(self, request):
- return False
-
- def logout(self, request):
- return False
+### BBB
+from zope.pluggableauth.plugins.ftpplugins import FTPCredentialsPlugin
Modified: zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/ftpplugins.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -1,12 +1,7 @@
<configure
xmlns="http://namespaces.zope.org/zope"
- i18n_domain="zope"
- >
+ i18n_domain="zope">
- <utility
- name="FTP Credentials"
- provides=".interfaces.ICredentialsPlugin"
- factory=".ftpplugins.FTPCredentialsPlugin"
- />
+ <include package="zope.pluggableauth.plugins" file="ftpplugins.zcml" />
</configure>
Modified: zope.app.authentication/trunk/src/zope/app/authentication/generic.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/generic.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/generic.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -16,79 +16,6 @@
$Id$
"""
__docformat__ = "reStructuredText"
-from zope.interface import implements
-from zope.authentication.interfaces import IUnauthenticatedPrincipal
-from zope.app.authentication import interfaces
-
-
-class NoChallengeCredentialsPlugin(object):
- """A plugin that doesn't challenge if the principal is authenticated.
-
- There are two reasonable ways to handle an unauthorized error for an
- authenticated principal:
-
- - Inform the user of the unauthorized error
-
- - Let the user login with a different set of credentials
-
- Since either approach is reasonable, we need to give the site manager
- some way of specifying one of the two policies.
-
- By default, a user will be challenged for a new set of credentials if
- unauthorized. A site manager can insert this plugin in the front of the
- plugin list to prevent that challenge from occurring. This will
- typically result in an 'Unauthorized' message to the user.
-
- The 'challenge' behavior of the plugin is simple. To illustrate, we'll
- create a plugin:
-
- >>> challenger = NoChallengeCredentialsPlugin()
-
- and a test request with an authenticated principal:
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
- >>> IUnauthenticatedPrincipal.providedBy(request.principal)
- False
-
- When we challenge using the plugin:
-
- >>> challenger.challenge(request)
- True
-
- we get a value that signals the PAU that this plugin successfully
- challenged the user (even though it actually did nothing). The PAU
- will stop trying to challenge and the user will not get a chance to
- provide different credentials. The result is typically an error message.
-
- On the other hand, if the user is unauthenticated:
-
- >>> class Principal(object):
- ... implements(IUnauthenticatedPrincipal)
- >>> request.setPrincipal(Principal())
- >>> IUnauthenticatedPrincipal.providedBy(request.principal)
- True
-
- the plugin challenge will return None:
-
- >>> print challenger.challenge(request)
- None
-
- signaling the PAU that it should try the next plugin for a challenge. If
- the PAU is configured properly, the user will receive a challenge and be
- allowed to provide different credentials.
- """
- implements(interfaces.ICredentialsPlugin)
-
- def extractCredentials(self, request):
- return None
-
- def challenge(self, request):
- if not IUnauthenticatedPrincipal.providedBy(request.principal):
- return True
- return None
-
- def logout(self, request):
- return False
-
+# BBB
+from zope.pluggableauth.plugins.generic import NoChallengeCredentialsPlugin
Modified: zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -16,127 +16,7 @@
$Id$
"""
__docformat__ = "reStructuredText"
-import base64
-from persistent import Persistent
-from zope.interface import implements, Interface
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.schema import TextLine
-from zope.container.contained import Contained
-from zope.app.authentication import interfaces
-
-
-class IHTTPBasicAuthRealm(Interface):
- """HTTP Basic Auth Realm
-
- Represents the realm string that is used during basic HTTP authentication
- """
-
- realm = TextLine(title=u'Realm',
- description=u'HTTP Basic Authentication Realm',
- required=True,
- default=u'Zope')
-
-
-class HTTPBasicAuthCredentialsPlugin(Persistent, Contained):
-
- implements(interfaces.ICredentialsPlugin, IHTTPBasicAuthRealm)
-
- realm = 'Zope'
-
- protocol = 'http auth'
-
- def extractCredentials(self, request):
- """Extracts HTTP basic auth credentials from a request.
-
- First we need to create a request that contains some credentials.
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest(
- ... environ={'HTTP_AUTHORIZATION': u'Basic bWdyOm1ncnB3'})
-
- Now create the plugin and get the credentials.
-
- >>> plugin = HTTPBasicAuthCredentialsPlugin()
- >>> plugin.extractCredentials(request)
- {'login': u'mgr', 'password': u'mgrpw'}
-
- Make sure we return `None`, if no authentication header has been
- specified.
-
- >>> print plugin.extractCredentials(TestRequest())
- None
-
- Also, this plugin can *only* handle basic authentication.
-
- >>> request = TestRequest(environ={'HTTP_AUTHORIZATION': 'foo bar'})
- >>> print plugin.extractCredentials(TestRequest())
- None
-
- This plugin only works with HTTP requests.
-
- >>> from zope.publisher.base import TestRequest
- >>> print plugin.extractCredentials(TestRequest('/'))
- None
-
- """
- if not IHTTPRequest.providedBy(request):
- return None
-
- if request._auth:
- if request._auth.lower().startswith(u'basic '):
- credentials = request._auth.split()[-1]
- login, password = base64.decodestring(credentials).split(':')
- return {'login': login.decode('utf-8'),
- 'password': password.decode('utf-8')}
- return None
-
- def challenge(self, request):
- """Issues an HTTP basic auth challenge for credentials.
-
- The challenge is issued by setting the appropriate response headers.
- To illustrate, we'll create a plugin:
-
- >>> plugin = HTTPBasicAuthCredentialsPlugin()
-
- The plugin adds its challenge to the HTTP response.
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
- >>> response = request.response
- >>> plugin.challenge(request)
- True
- >>> response._status
- 401
- >>> response.getHeader('WWW-Authenticate', literal=True)
- 'basic realm="Zope"'
-
- Notice that the realm is quoted, as per RFC 2617.
-
- The plugin only works with HTTP requests.
-
- >>> from zope.publisher.base import TestRequest
- >>> request = TestRequest('/')
- >>> response = request.response
- >>> print plugin.challenge(request)
- False
-
- """
- if not IHTTPRequest.providedBy(request):
- return False
- request.response.setHeader("WWW-Authenticate",
- 'basic realm="%s"' % self.realm,
- literal=True)
- request.response.setStatus(401)
- return True
-
- def logout(self, request):
- """Always returns False as logout is not supported by basic auth.
-
- >>> plugin = HTTPBasicAuthCredentialsPlugin()
- >>> from zope.publisher.browser import TestRequest
- >>> plugin.logout(TestRequest())
- False
-
- """
- return False
+### BBB
+from zope.pluggableauth.plugins.httpplugins import (
+ IHTTPBasicAuthRealm, HTTPBasicAuthCredentialsPlugin)
Modified: zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/httpplugins.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -3,20 +3,16 @@
i18n_domain="zope"
>
- <utility
- name="Zope Realm Basic-Auth"
- provides=".interfaces.ICredentialsPlugin"
- factory=".httpplugins.HTTPBasicAuthCredentialsPlugin"
- />
+ <include package="zope.pluggableauth.plugins" file="httpplugins.zcml" />
- <class class=".httpplugins.HTTPBasicAuthCredentialsPlugin">
+ <class class="zope.pluggableauth.plugins.httpplugins.HTTPBasicAuthCredentialsPlugin">
<implements
interface="zope.annotation.interfaces.IAttributeAnnotatable"
/>
<require
permission="zope.ManageServices"
- interface=".httpplugins.IHTTPBasicAuthRealm"
- set_schema=".httpplugins.IHTTPBasicAuthRealm"
+ interface="zope.pluggableauth.plugins.httpplugins.IHTTPBasicAuthRealm"
+ set_schema="zope.pluggableauth.plugins.httpplugins.IHTTPBasicAuthRealm"
/>
</class>
Modified: zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/interfaces.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -21,156 +21,20 @@
import zope.schema
import zope.security.interfaces
from zope.app.authentication.i18n import ZopeMessageFactory as _
-from zope.authentication.interfaces import ILogout
-from zope.container.constraints import contains, containers
-from zope.container.interfaces import IContainer
# BBB: the password managers were moved into zope.password package.
from zope.password.interfaces import IPasswordManager
-class IPlugin(zope.interface.Interface):
- """A plugin for a pluggable authentication component."""
+# BBB: using zope.pluggableauth
+from zope.pluggableauth.interfaces import (
+ IPlugin, IAuthenticatorPlugin, ICredentialsPlugin,
+ IPluggableAuthentication, IPrincipalInfo,
+ IFoundPrincipalFactory, IPrincipalFactory, IAuthenticatedPrincipalFactory,
+ IPrincipalCreated, IAuthenticatedPrincipalCreated,
+ AuthenticatedPrincipalCreated, IFoundPrincipalCreated,
+ FoundPrincipalCreated, IQueriableAuthenticator)
-class IPluggableAuthentication(ILogout, IContainer):
- """Provides authentication services with the help of various plugins.
-
- IPluggableAuthentication implementations will also implement
- zope.authentication.interfaces.IAuthentication. The `authenticate` method
- of this interface in an IPluggableAuthentication should annotate the
- IPrincipalInfo with the credentials plugin and authentication plugin used.
- The `getPrincipal` method should annotate the IPrincipalInfo with the
- authentication plugin used.
- """
-
- contains(IPlugin)
-
- credentialsPlugins = zope.schema.List(
- title=_('Credentials Plugins'),
- description=_("""Used for extracting credentials.
- Names may be of ids of non-utility ICredentialsPlugins contained in
- the IPluggableAuthentication, or names of registered
- ICredentialsPlugins utilities. Contained non-utility ids mask
- utility names."""),
- value_type=zope.schema.Choice(vocabulary='CredentialsPlugins'),
- default=[],
- )
-
- authenticatorPlugins = zope.schema.List(
- title=_('Authenticator Plugins'),
- description=_("""Used for converting credentials to principals.
- Names may be of ids of non-utility IAuthenticatorPlugins contained in
- the IPluggableAuthentication, or names of registered
- IAuthenticatorPlugins utilities. Contained non-utility ids mask
- utility names."""),
- value_type=zope.schema.Choice(vocabulary='AuthenticatorPlugins'),
- default=[],
- )
-
- def getCredentialsPlugins():
- """Return iterable of (plugin name, actual credentials plugin) pairs.
- Looks up names in credentialsPlugins as contained ids of non-utility
- ICredentialsPlugins first, then as registered ICredentialsPlugin
- utilities. Names that do not resolve are ignored."""
-
- def getAuthenticatorPlugins():
- """Return iterable of (plugin name, actual authenticator plugin) pairs.
- Looks up names in authenticatorPlugins as contained ids of non-utility
- IAuthenticatorPlugins first, then as registered IAuthenticatorPlugin
- utilities. Names that do not resolve are ignored."""
-
- prefix = zope.schema.TextLine(
- title=_('Prefix'),
- default=u'',
- required=True,
- readonly=True,
- )
-
- def logout(request):
- """Performs a logout by delegating to its authenticator plugins."""
-
-
-class ICredentialsPlugin(IPlugin):
- """Handles credentials extraction and challenges per request."""
-
- containers(IPluggableAuthentication)
-
- challengeProtocol = zope.interface.Attribute(
- """A challenge protocol used by the plugin.
-
- If a credentials plugin works with other credentials pluggins, it
- and the other cooperating plugins should specify a common (non-None)
- protocol. If a plugin returns True from its challenge method, then
- other credentials plugins will be called only if they have the same
- protocol.
- """)
-
- def extractCredentials(request):
- """Ties to extract credentials from a request.
-
- A return value of None indicates that no credentials could be found.
- Any other return value is treated as valid credentials.
- """
-
- def challenge(request):
- """Possibly issues a challenge.
-
- This is typically done in a protocol-specific way.
-
- If a challenge was issued, return True, otherwise return False.
- """
-
- def logout(request):
- """Possibly logout.
-
- If a logout was performed, return True, otherwise return False.
- """
-
-class IAuthenticatorPlugin(IPlugin):
- """Authenticates a principal using credentials.
-
- An authenticator may also be responsible for providing information
- about and creating principals.
- """
- containers(IPluggableAuthentication)
-
- def authenticateCredentials(credentials):
- """Authenticates credentials.
-
- If the credentials can be authenticated, return an object that provides
- IPrincipalInfo. If the plugin cannot authenticate the credentials,
- returns None.
- """
-
- def principalInfo(id):
- """Returns an IPrincipalInfo object for the specified principal id.
-
- If the plugin cannot find information for the id, returns None.
- """
-
-
-class IPrincipalInfo(zope.interface.Interface):
- """Minimal information about a principal."""
-
- id = zope.interface.Attribute("The principal id.")
-
- title = zope.interface.Attribute("The principal title.")
-
- description = zope.interface.Attribute("A description of the principal.")
-
- credentialsPlugin = zope.interface.Attribute(
- """Plugin used to generate the credentials for this principal info.
-
- Optional. Should be set in IPluggableAuthentication.authenticate.
- """)
-
- authenticatorPlugin = zope.interface.Attribute(
- """Plugin used to authenticate the credentials for this principal info.
-
- Optional. Should be set in IPluggableAuthentication.authenticate and
- IPluggableAuthentication.getPrincipal.
- """)
-
class IPrincipal(zope.security.interfaces.IGroupClosureAwarePrincipal):
groups = zope.schema.List(
@@ -187,86 +51,7 @@
value_type=zope.schema.TextLine(),
required=False)
-class IPrincipalFactory(zope.interface.Interface):
- """A principal factory."""
- def __call__(authentication):
- """Creates a principal.
-
- The authentication utility that called the factory is passed
- and should be included in the principal-created event.
- """
-
-
-class IFoundPrincipalFactory(IPrincipalFactory):
- """A found principal factory."""
-
-
-class IAuthenticatedPrincipalFactory(IPrincipalFactory):
- """An authenticated principal factory."""
-
-
-class IPrincipalCreated(zope.interface.Interface):
- """A principal has been created."""
-
- principal = zope.interface.Attribute("The principal that was created")
-
- authentication = zope.interface.Attribute(
- "The authentication utility that created the principal")
-
- info = zope.interface.Attribute("An object providing IPrincipalInfo.")
-
-
-class IAuthenticatedPrincipalCreated(IPrincipalCreated):
- """A principal has been created by way of an authentication operation."""
-
- request = zope.interface.Attribute(
- "The request the user was authenticated against")
-
-
-class AuthenticatedPrincipalCreated:
- """
- >>> from zope.interface.verify import verifyObject
- >>> event = AuthenticatedPrincipalCreated("authentication", "principal",
- ... "info", "request")
- >>> verifyObject(IAuthenticatedPrincipalCreated, event)
- True
- """
-
- zope.interface.implements(IAuthenticatedPrincipalCreated)
-
- def __init__(self, authentication, principal, info, request):
- self.authentication = authentication
- self.principal = principal
- self.info = info
- self.request = request
-
-
-class IFoundPrincipalCreated(IPrincipalCreated):
- """A principal has been created by way of a search operation."""
-
-
-class FoundPrincipalCreated:
- """
- >>> from zope.interface.verify import verifyObject
- >>> event = FoundPrincipalCreated("authentication", "principal",
- ... "info")
- >>> verifyObject(IFoundPrincipalCreated, event)
- True
- """
-
- zope.interface.implements(IFoundPrincipalCreated)
-
- def __init__(self, authentication, principal, info):
- self.authentication = authentication
- self.principal = principal
- self.info = info
-
-
-class IQueriableAuthenticator(zope.interface.Interface):
- """Indicates the authenticator provides a search UI for principals."""
-
-
class IQuerySchemaSearch(zope.interface.Interface):
"""An interface for searching using schema-constrained input."""
@@ -292,6 +77,7 @@
returned.
"""
+
class IGroupAdded(zope.interface.Interface):
"""A group has been added."""
@@ -314,18 +100,21 @@
def __repr__(self):
return "<GroupAdded %r>" % self.group.id
+
class IPrincipalsAddedToGroup(zope.interface.Interface):
group_id = zope.interface.Attribute(
'the id of the group to which the principal was added')
principal_ids = zope.interface.Attribute(
'an iterable of one or more ids of principals added')
+
class IPrincipalsRemovedFromGroup(zope.interface.Interface):
group_id = zope.interface.Attribute(
'the id of the group from which the principal was removed')
principal_ids = zope.interface.Attribute(
'an iterable of one or more ids of principals removed')
+
class AbstractMembersChanged(object):
def __init__(self, principal_ids, group_id):
@@ -336,8 +125,10 @@
return "<%s %r %r>" % (
self.__class__.__name__, sorted(self.principal_ids), self.group_id)
+
class PrincipalsAddedToGroup(AbstractMembersChanged):
zope.interface.implements(IPrincipalsAddedToGroup)
+
class PrincipalsRemovedFromGroup(AbstractMembersChanged):
zope.interface.implements(IPrincipalsRemovedFromGroup)
Modified: zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -18,24 +18,25 @@
__docformat__ = "reStructuredText"
from persistent import Persistent
-from zope import interface
-from zope import component
-from zope.event import notify
-from zope.schema import Text, TextLine, Password, Choice
-from zope.publisher.interfaces import IRequest
-
-from zope.authentication.interfaces import IAuthentication
-from zope.container.interfaces import DuplicateIDError
-from zope.container.contained import Contained
-from zope.container.constraints import contains, containers
+from zope.app.authentication.i18n import ZopeMessageFactory as _
+from zope.app.authentication.interfaces import IQuerySchemaSearch
+from zope.component import getUtility
from zope.container.btree import BTreeContainer
+from zope.container.constraints import contains, containers
+from zope.container.contained import Contained
+from zope.container.interfaces import DuplicateIDError
+from zope.interface import implements, Interface
from zope.password.interfaces import IPasswordManager
-from zope.app.authentication.i18n import ZopeMessageFactory as _
+from zope.schema import Text, TextLine, Password, Choice
-from zope.app.authentication import interfaces
+# BBB using zope.pluggableauth
+from zope.pluggableauth.interfaces import IAuthenticatorPlugin
+from zope.pluggableauth.factories import (
+ Principal, PrincipalInfo,
+ FoundPrincipalFactory, AuthenticatedPrincipalFactory)
+
-
-class IInternalPrincipal(interface.Interface):
+class IInternalPrincipal(Interface):
"""Principal information"""
login = TextLine(
@@ -73,7 +74,7 @@
default=u'')
-class IInternalPrincipalContainer(interface.Interface):
+class IInternalPrincipalContainer(Interface):
"""A container that contains internal principals."""
prefix = TextLine(
@@ -98,13 +99,13 @@
contains(IInternalPrincipal)
-class IInternalPrincipalContained(interface.Interface):
+class IInternalPrincipalContained(Interface):
"""Principal information"""
containers(IInternalPrincipalContainer)
-class ISearchSchema(interface.Interface):
+class ISearchSchema(Interface):
"""Search Interface for this Principal Provider"""
search = TextLine(
@@ -118,7 +119,7 @@
class InternalPrincipal(Persistent, Contained):
"""An internal principal for Persistent Principal Folder."""
- interface.implements(IInternalPrincipal, IInternalPrincipalContained)
+ implements(IInternalPrincipal, IInternalPrincipalContained)
# If you're searching for self._passwordManagerName, or self._password
# probably you just need to evolve the database to new generation
@@ -141,8 +142,7 @@
passwordManagerName = property(getPasswordManagerName)
def _getPasswordManager(self):
- return component.getUtility(
- IPasswordManager, self.passwordManagerName)
+ return getUtility(IPasswordManager, self.passwordManagerName)
def getPassword(self):
return self._password
@@ -159,9 +159,6 @@
passwordManager = self._getPasswordManager()
return passwordManager.checkPassword(self.password, password)
- def getPassword(self):
- return self._password
-
def getLogin(self):
return self._login
@@ -178,45 +175,15 @@
login = property(getLogin, setLogin)
-class PrincipalInfo(object):
- """An implementation of IPrincipalInfo used by the principal folder.
-
- A principal info is created with id, login, title, and description:
-
- >>> info = PrincipalInfo('users.foo', 'foo', 'Foo', 'An over-used term.')
- >>> info
- PrincipalInfo('users.foo')
- >>> info.id
- 'users.foo'
- >>> info.login
- 'foo'
- >>> info.title
- 'Foo'
- >>> info.description
- 'An over-used term.'
-
- """
- interface.implements(interfaces.IPrincipalInfo)
-
- def __init__(self, id, login, title, description):
- self.id = id
- self.login = login
- self.title = title
- self.description = description
-
- def __repr__(self):
- return 'PrincipalInfo(%r)' % self.id
-
-
class PrincipalFolder(BTreeContainer):
"""A Persistent Principal Folder and Authentication plugin.
See principalfolder.txt for details.
"""
- interface.implements(interfaces.IAuthenticatorPlugin,
- interfaces.IQuerySchemaSearch,
- IInternalPrincipalContainer)
+ implements(IAuthenticatorPlugin,
+ IQuerySchemaSearch,
+ IInternalPrincipalContainer)
schema = ISearchSchema
@@ -317,250 +284,3 @@
or (batch_size is not None and n > batch_size)):
n += 1
yield self.prefix + value.__name__
-
-class Principal(object):
- """A group-aware implementation of zope.security.interfaces.IPrincipal.
-
- A principal is created with an ID:
-
- >>> p = Principal(1)
- >>> p
- Principal(1)
- >>> p.id
- 1
-
- title and description may also be provided:
-
- >>> p = Principal('george', 'George', 'A site member.')
- >>> p
- Principal('george')
- >>> p.id
- 'george'
- >>> p.title
- 'George'
- >>> p.description
- 'A site member.'
-
- The `groups` is a simple list, filled in by plugins.
-
- >>> p.groups
- []
-
- The `allGroups` attribute is a readonly iterable of the full closure of the
- groups in the `groups` attribute--that is, if the principal is a direct
- member of the 'Administrators' group, and the 'Administrators' group is
- a member of the 'Reviewers' group, then p.groups would be
- ['Administrators'] and list(p.allGroups) would be
- ['Administrators', 'Reviewers'].
-
- To illustrate this, we'll need to set up a dummy authentication utility,
- and a few principals. Our main principal will also gain some groups, as if
- plugins had added the groups to the list. This is all setup--skip to the
- next block to actually see `allGroups` in action.
-
- >>> p.groups.extend(
- ... ['content_administrators', 'zope_3_project',
- ... 'list_administrators', 'zpug'])
- >>> editor = Principal('editors', 'Content Editors')
- >>> creator = Principal('creators', 'Content Creators')
- >>> reviewer = Principal('reviewers', 'Content Reviewers')
- >>> reviewer.groups.extend(['editors', 'creators'])
- >>> usermanager = Principal('user_managers', 'User Managers')
- >>> contentAdmin = Principal(
- ... 'content_administrators', 'Content Administrators')
- >>> contentAdmin.groups.extend(['reviewers', 'user_managers'])
- >>> zope3Dev = Principal('zope_3_project', 'Zope 3 Developer')
- >>> zope3ListAdmin = Principal(
- ... 'zope_3_list_admin', 'Zope 3 List Administrators')
- >>> zope3ListAdmin.groups.append('zope_3_project') # duplicate, but
- ... # should only appear in allGroups once
- >>> listAdmin = Principal('list_administrators', 'List Administrators')
- >>> listAdmin.groups.append('zope_3_list_admin')
- >>> zpugMember = Principal('zpug', 'ZPUG Member')
- >>> martians = Principal('martians', 'Martians') # not in p's allGroups
- >>> group_data = dict((p.id, p) for p in (
- ... editor, creator, reviewer, usermanager, contentAdmin,
- ... zope3Dev, zope3ListAdmin, listAdmin, zpugMember, martians))
- >>> class DemoAuth(object):
- ... interface.implements(IAuthentication)
- ... def getPrincipal(self, id):
- ... return group_data[id]
- ...
- >>> demoAuth = DemoAuth()
- >>> component.provideUtility(demoAuth)
-
- Now, we have a user with the following groups (lowest level are p's direct
- groups, and lines show membership):
-
- editors creators
- \------/
- | zope_3_project (duplicate)
- reviewers user_managers |
- \---------/ zope_3_list_admin
- | |
- content_administrators zope_3_project list_administrators zpug
-
- The allGroups value includes all of the shown groups, and with
- 'zope_3_project' only appearing once.
-
- >>> p.groups # doctest: +NORMALIZE_WHITESPACE
- ['content_administrators', 'zope_3_project', 'list_administrators',
- 'zpug']
- >>> list(p.allGroups) # doctest: +NORMALIZE_WHITESPACE
- ['content_administrators', 'reviewers', 'editors', 'creators',
- 'user_managers', 'zope_3_project', 'list_administrators',
- 'zope_3_list_admin', 'zpug']
- """
- interface.implements(interfaces.IPrincipal)
-
- def __init__(self, id, title=u'', description=u''):
- self.id = id
- self.title = title
- self.description = description
- self.groups = []
-
- def __repr__(self):
- return 'Principal(%r)' % self.id
-
- @property
- def allGroups(self):
- if self.groups:
- seen = set()
- principals = component.getUtility(IAuthentication)
- stack = [iter(self.groups)]
- while stack:
- try:
- group_id = stack[-1].next()
- except StopIteration:
- stack.pop()
- else:
- if group_id not in seen:
- yield group_id
- seen.add(group_id)
- group = principals.getPrincipal(group_id)
- stack.append(iter(group.groups))
-
-class AuthenticatedPrincipalFactory(object):
- """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('users.mary', 'mary', 'Mary', 'The site admin.')
- >>> from zope.publisher.base import TestRequest
- >>> request = TestRequest('/')
- >>> factory = AuthenticatedPrincipalFactory(info, request)
-
- The factory must be called with a pluggable-authentication object:
-
- >>> class Auth:
- ... prefix = 'auth.'
- >>> auth = Auth()
-
- >>> principal = factory(auth)
-
- The factory uses the pluggable authentication and the info to
- create a principal with the same ID, title, and description:
-
- >>> principal.id
- 'auth.users.mary'
- >>> principal.title
- 'Mary'
- >>> principal.description
- 'The site admin.'
-
- It also fires an AuthenticatedPrincipalCreatedEvent:
-
- >>> from zope.component.eventtesting import getEvents
- >>> [event] = getEvents(interfaces.IAuthenticatedPrincipalCreated)
- >>> event.principal is principal, event.authentication is auth
- (True, True)
- >>> event.info
- PrincipalInfo('users.mary')
- >>> event.request is request
- True
-
- Listeners can subscribe to this event to perform additional operations
- when the authenticated principal is created.
-
- For information on how factories are used in the authentication process,
- see README.txt.
- """
- component.adapts(interfaces.IPrincipalInfo, IRequest)
-
- interface.implements(interfaces.IAuthenticatedPrincipalFactory)
-
- def __init__(self, info, request):
- self.info = info
- self.request = request
-
- def __call__(self, authentication):
- principal = Principal(authentication.prefix + self.info.id,
- self.info.title,
- self.info.description)
- notify(interfaces.AuthenticatedPrincipalCreated(
- authentication, principal, self.info, self.request))
- return principal
-
-
-class FoundPrincipalFactory(object):
- """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('users.sam', 'sam', 'Sam', 'A site user.')
- >>> factory = FoundPrincipalFactory(info)
-
- The factory must be called with a pluggable-authentication object:
-
- >>> class Auth:
- ... prefix = 'auth.'
- >>> auth = Auth()
-
- >>> principal = factory(auth)
-
- The factory uses the pluggable-authentication object and the info
- to create a principal with the same ID, title, and description:
-
- >>> principal.id
- 'auth.users.sam'
- >>> principal.title
- 'Sam'
- >>> principal.description
- 'A site user.'
-
- It also fires a FoundPrincipalCreatedEvent:
-
- >>> from zope.component.eventtesting import getEvents
- >>> [event] = getEvents(interfaces.IFoundPrincipalCreated)
- >>> event.principal is principal, event.authentication is auth
- (True, True)
- >>> event.info
- PrincipalInfo('users.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
-
- def __call__(self, authentication):
- principal = Principal(authentication.prefix + self.info.id,
- self.info.title,
- self.info.description)
- notify(interfaces.FoundPrincipalCreated(authentication,
- principal, self.info))
- return principal
Modified: zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/principalfolder.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -1,8 +1,13 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- i18n_domain="zope"
- >
+<configure xmlns="http://namespaces.zope.org/zope" i18n_domain="zope">
+ <adapter
+ factory="zope.pluggableauth.factories.FoundPrincipalFactory"
+ />
+
+ <adapter
+ factory="zope.pluggableauth.factories.AuthenticatedPrincipalFactory"
+ />
+
<class class=".principalfolder.InternalPrincipal">
<require
permission="zope.ManageServices"
@@ -35,10 +40,6 @@
factory=".idpicker.IdPicker"
/>
- <adapter factory=".principalfolder.FoundPrincipalFactory" />
-
- <adapter factory=".principalfolder.AuthenticatedPrincipalFactory" />
-
<include package=".browser" file="principalfolder.zcml" />
<!-- Registering documentation with API doc -->
Modified: zope.app.authentication/trunk/src/zope/app/authentication/session.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/session.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/session.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -18,284 +18,8 @@
"""
__docformat__ = 'restructuredtext'
-import transaction
-from persistent import Persistent
-from urllib import urlencode
-
-from zope.interface import implements, Interface
-from zope.schema import TextLine
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.session.interfaces import ISession
-from zope.traversing.browser.absoluteurl import absoluteURL
-
-from zope.site import hooks
-from zope.container.contained import Contained
-from zope.app.authentication.interfaces import ICredentialsPlugin
-
-class ISessionCredentials(Interface):
- """ Interface for storing and accessing credentials in a session.
-
- We use a real class with interface here to prevent unauthorized
- access to the credentials.
- """
-
- def __init__(login, password):
- pass
-
- def getLogin():
- """Return login name."""
-
- def getPassword():
- """Return password."""
-
-
-class SessionCredentials(object):
- """Credentials class for use with sessions.
-
- A session credential is created with a login and a password:
-
- >>> cred = SessionCredentials('scott', 'tiger')
-
- Logins are read using getLogin:
- >>> cred.getLogin()
- 'scott'
-
- and passwords with getPassword:
-
- >>> cred.getPassword()
- 'tiger'
-
- """
- implements(ISessionCredentials)
-
- def __init__(self, login, password):
- self.login = login
- self.password = password
-
- def getLogin(self): return self.login
-
- def getPassword(self): return self.password
-
- def __str__(self): return self.getLogin() + ':' + self.getPassword()
-
-
-class IBrowserFormChallenger(Interface):
- """A challenger that uses a browser form to collect user credentials."""
-
- loginpagename = TextLine(
- title=u'Loginpagename',
- description=u"""Name of the login form used by challenger.
-
- The form must provide 'login' and 'password' input fields.
- """,
- default=u'loginForm.html')
-
- loginfield = TextLine(
- title=u'Loginfield',
- description=u"Field of the login page in which is looked for the login user name.",
- default=u"login")
-
- passwordfield = TextLine(
- title=u'Passwordfield',
- description=u"Field of the login page in which is looked for the password.",
- default=u"password")
-
-
-class SessionCredentialsPlugin(Persistent, Contained):
- """A credentials plugin that uses Zope sessions to get/store credentials.
-
- To illustrate how a session plugin works, we'll first setup some session
- machinery:
-
- >>> from zope.session.session import RAMSessionDataContainer
- >>> from tests import sessionSetUp
- >>> sessionSetUp(RAMSessionDataContainer)
-
- This lets us retrieve the same session info from any test request, which
- simulates what happens when a user submits a session ID as a cookie.
-
- We also need a session plugin:
-
- >>> plugin = SessionCredentialsPlugin()
-
- A session plugin uses an ISession component to store the last set of
- credentials it gets from a request. Credentials can be retrieved from
- subsequent requests using the session-stored credentials.
-
- Our test environment is initially configured without credentials:
-
- >>> from tests import sessionSetUp
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
- >>> print plugin.extractCredentials(request)
- None
-
- We must explicitly provide credentials once so the plugin can store
- them in a session:
-
- >>> request = TestRequest(login='scott', password='tiger')
- >>> plugin.extractCredentials(request)
- {'login': 'scott', 'password': 'tiger'}
-
- Subsequent requests now have access to the credentials even if they're
- not explicitly in the request:
-
- >>> plugin.extractCredentials(TestRequest())
- {'login': 'scott', 'password': 'tiger'}
-
- We can always provide new credentials explicitly in the request:
-
- >>> plugin.extractCredentials(TestRequest(
- ... login='harry', password='hirsch'))
- {'login': 'harry', 'password': 'hirsch'}
-
- and these will be used on subsequent requests:
-
- >>> plugin.extractCredentials(TestRequest())
- {'login': 'harry', 'password': 'hirsch'}
-
- We can also change the fields from which the credentials are extracted:
-
- >>> plugin.loginfield = "my_new_login_field"
- >>> plugin.passwordfield = "my_new_password_field"
-
- Now we build a request that uses the new fields:
-
- >>> request = TestRequest(my_new_login_field='luke', my_new_password_field='the_force')
-
- The plugin now extracts the credentials information from these new fields:
-
- >>> plugin.extractCredentials(request)
- {'login': 'luke', 'password': 'the_force'}
-
- Finally, we clear the session credentials using the logout method:
-
- >>> plugin.logout(TestRequest())
- True
- >>> print plugin.extractCredentials(TestRequest())
- None
-
- """
- implements(ICredentialsPlugin, IBrowserFormChallenger)
-
- loginpagename = 'loginForm.html'
- loginfield = 'login'
- passwordfield = 'password'
-
- def extractCredentials(self, request):
- """Extracts credentials from a session if they exist."""
- if not IHTTPRequest.providedBy(request):
- return None
- session = ISession(request)
- sessionData = session.get(
- 'zope.app.authentication.browserplugins')
- login = request.get(self.loginfield, None)
- password = request.get(self.passwordfield, None)
- credentials = None
-
- if login and password:
- credentials = SessionCredentials(login, password)
- elif not sessionData:
- return None
- sessionData = session[
- 'zope.app.authentication.browserplugins']
- if credentials:
- sessionData['credentials'] = credentials
- else:
- credentials = sessionData.get('credentials', None)
- if not credentials:
- return None
- return {'login': credentials.getLogin(),
- 'password': credentials.getPassword()}
-
- def challenge(self, request):
- """Challenges by redirecting to a login form.
-
- To illustrate, we'll create a test request:
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
-
- and confirm its response's initial status and 'location' header:
-
- >>> request.response.getStatus()
- 599
- >>> request.response.getHeader('location')
-
- When we issue a challenge using a session plugin:
-
- >>> plugin = SessionCredentialsPlugin()
- >>> plugin.challenge(request)
- True
-
- we get a redirect:
-
- >>> request.response.getStatus()
- 302
- >>> request.response.getHeader('location')
- 'http://127.0.0.1/@@loginForm.html?camefrom=%2F'
-
- The plugin redirects to the page defined by the loginpagename
- attribute:
-
- >>> plugin.loginpagename = 'mylogin.html'
- >>> plugin.challenge(request)
- True
- >>> request.response.getHeader('location')
- 'http://127.0.0.1/@@mylogin.html?camefrom=%2F'
-
- It also provides the request URL as a 'camefrom' GET style parameter.
- To illustrate, we'll pretend we've traversed a couple names:
-
- >>> env = {
- ... 'REQUEST_URI': '/foo/bar/folder/page%201.html?q=value',
- ... 'QUERY_STRING': 'q=value'
- ... }
- >>> request = TestRequest(environ=env)
- >>> request._traversed_names = [u'foo', u'bar']
- >>> request._traversal_stack = [u'page 1.html', u'folder']
- >>> request['REQUEST_URI']
- '/foo/bar/folder/page%201.html?q=value'
-
- When we challenge:
-
- >>> plugin.challenge(request)
- True
-
- We see the 'camefrom' points to the requested URL:
-
- >>> request.response.getHeader('location') # doctest: +ELLIPSIS
- '.../@@mylogin.html?camefrom=%2Ffoo%2Fbar%2Ffolder%2Fpage+1.html%3Fq%3Dvalue'
-
- This can be used by the login form to redirect the user back to the
- originating URL upon successful authentication.
- """
- if not IHTTPRequest.providedBy(request):
- return False
-
- site = hooks.getSite()
- # We need the traversal stack to complete the 'camefrom' parameter
- stack = request.getTraversalStack()
- stack.reverse()
- # Better to add the query string, if present
- query = request.get('QUERY_STRING')
-
- camefrom = '/'.join([request.getURL(path_only=True)] + stack)
- if query:
- camefrom = camefrom + '?' + query
- url = '%s/@@%s?%s' % (absoluteURL(site, request),
- self.loginpagename,
- urlencode({'camefrom': camefrom}))
- request.response.redirect(url)
- return True
-
- def logout(self, request):
- """Performs logout by clearing session data credentials."""
- if not IHTTPRequest.providedBy(request):
- return False
-
- sessionData = ISession(request)[
- 'zope.app.authentication.browserplugins']
- sessionData['credentials'] = None
- transaction.commit()
- return True
+### BBB
+from zope.pluggableauth.plugins.session import (
+ ISessionCredentials, SessionCredentials,
+ IBrowserFormChallenger, SessionCredentialsPlugin,
+ )
Modified: zope.app.authentication/trunk/src/zope/app/authentication/session.zcml
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/session.zcml 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/session.zcml 2010-02-06 11:16:44 UTC (rev 108827)
@@ -3,13 +3,9 @@
i18n_domain="zope"
>
- <utility
- name="Session Credentials"
- provides=".interfaces.ICredentialsPlugin"
- factory=".session.SessionCredentialsPlugin"
- />
+ <include package="zope.pluggableauth.plugins" file="session.zcml" />
- <class class=".session.SessionCredentialsPlugin">
+ <class class="zope.pluggableauth.plugins.session.SessionCredentialsPlugin">
<implements
interface="zope.annotation.interfaces.IAttributeAnnotatable"
@@ -17,8 +13,8 @@
<require
permission="zope.ManageServices"
- interface=".session.IBrowserFormChallenger"
- set_schema=".session.IBrowserFormChallenger"
+ interface="zope.pluggableauth.plugins.session.IBrowserFormChallenger"
+ set_schema="zope.pluggableauth.plugins.session.IBrowserFormChallenger"
/>
</class>
Modified: zope.app.authentication/trunk/src/zope/app/authentication/tests.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/tests.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/tests.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -34,7 +34,7 @@
from zope.session.http import CookieClientIdManager
from zope.publisher import base
-from zope.app.authentication.session import SessionCredentialsPlugin
+from zope.pluggableauth.plugins.session import SessionCredentialsPlugin
class TestClientId(object):
Modified: zope.app.authentication/trunk/src/zope/app/authentication/vocabulary.py
===================================================================
--- zope.app.authentication/trunk/src/zope/app/authentication/vocabulary.py 2010-02-06 03:44:46 UTC (rev 108826)
+++ zope.app.authentication/trunk/src/zope/app/authentication/vocabulary.py 2010-02-06 11:16:44 UTC (rev 108827)
@@ -25,8 +25,8 @@
from zope.schema.interfaces import IVocabularyFactory
from zope.app.authentication.i18n import ZopeMessageFactory as _
+from zope.pluggableauth import interfaces
-from zope.app.authentication import interfaces
UTILITY_TITLE = _(
'zope.app.authentication.vocabulary-utility-plugin-title',
More information about the checkins
mailing list