[Zope3-checkins] SVN: Zope3/trunk/ Converted Authentication Service
to be a utility. Renamed PAS to
Stephan Richter
srichter at cosmos.phy.tufts.edu
Mon Dec 20 22:34:47 EST 2004
Log message for revision 28663:
Converted Authentication Service to be a utility. Renamed PAS to
PAU.
Changed:
U Zope3/trunk/doc/CHANGES.txt
D Zope3/trunk/package-includes/pas-configure.zcml
A Zope3/trunk/package-includes/pau-configure.zcml
U Zope3/trunk/src/zope/app/exception/browser/tests/test_unauthorized.py
U Zope3/trunk/src/zope/app/exception/browser/unauthorized.py
U Zope3/trunk/src/zope/app/homefolder/tests.py
D Zope3/trunk/src/zope/app/pas/
A Zope3/trunk/src/zope/app/pau/
D Zope3/trunk/src/zope/app/pau/README.txt
A Zope3/trunk/src/zope/app/pau/README.txt
U Zope3/trunk/src/zope/app/pau/__init__.py
U Zope3/trunk/src/zope/app/pau/authenticationplugins.zcml
U Zope3/trunk/src/zope/app/pau/browser/configure.zcml
U Zope3/trunk/src/zope/app/pau/browser/groupfolder.txt
U Zope3/trunk/src/zope/app/pau/browser/principalfolder.txt
U Zope3/trunk/src/zope/app/pau/browser/schemasearch.py
U Zope3/trunk/src/zope/app/pau/browser/schemasearch.txt
U Zope3/trunk/src/zope/app/pau/browserplugins.py
D Zope3/trunk/src/zope/app/pau/challengeplugins.zcml
A Zope3/trunk/src/zope/app/pau/challengeplugins.zcml
U Zope3/trunk/src/zope/app/pau/configure.zcml
U Zope3/trunk/src/zope/app/pau/groupfolder.py
U Zope3/trunk/src/zope/app/pau/groupfolder.txt
U Zope3/trunk/src/zope/app/pau/groupfolder.zcml
U Zope3/trunk/src/zope/app/pau/idpicker.txt
U Zope3/trunk/src/zope/app/pau/interfaces.py
D Zope3/trunk/src/zope/app/pau/pas.py
A Zope3/trunk/src/zope/app/pau/pau.py
D Zope3/trunk/src/zope/app/pau/principalfolder.py
A Zope3/trunk/src/zope/app/pau/principalfolder.py
U Zope3/trunk/src/zope/app/pau/principalfolder.txt
U Zope3/trunk/src/zope/app/pau/principalplugins.py
U Zope3/trunk/src/zope/app/pau/principalplugins.zcml
U Zope3/trunk/src/zope/app/pau/sql.py
U Zope3/trunk/src/zope/app/pau/tests.py
U Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py
U Zope3/trunk/src/zope/app/publication/zopepublication.py
U Zope3/trunk/src/zope/app/security/browser/auth.py
D Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt
A Zope3/trunk/src/zope/app/security/browser/authutilitysearchview.txt
U Zope3/trunk/src/zope/app/security/browser/configure.zcml
U Zope3/trunk/src/zope/app/security/browser/principalterms.py
U Zope3/trunk/src/zope/app/security/browser/principalterms.txt
U Zope3/trunk/src/zope/app/security/browser/tests.py
U Zope3/trunk/src/zope/app/security/configure.zcml
U Zope3/trunk/src/zope/app/security/interfaces.py
U Zope3/trunk/src/zope/app/security/principal.py
U Zope3/trunk/src/zope/app/security/principalregistry.py
U Zope3/trunk/src/zope/app/security/tests/test_securitydirectives.py
U Zope3/trunk/src/zope/app/security/vocabulary.py
U Zope3/trunk/src/zope/app/securitypolicy/browser/granting.txt
U Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalpermissionmanager.py
U Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalrolemanager.py
U Zope3/trunk/src/zope/app/securitypolicy/tests/test_securitydirectives.py
U Zope3/trunk/src/zope/app/securitypolicy/tests/test_zopepolicy.py
U Zope3/trunk/src/zope/app/securitypolicy/zopepolicy.txt
U Zope3/trunk/src/zope/app/workflow/tests/workflowsetup.py
U Zope3/trunk/src/zope/app/zapi/README.txt
U Zope3/trunk/src/zope/app/zapi/__init__.py
U Zope3/trunk/src/zope/app/zapi/tests.py
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/doc/CHANGES.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -171,6 +171,9 @@
+ Converted Error Reporting Service to a utility. Added database
evolution code to convert all serice instances to utilities.
+ + Converted Authentication Service to be a utility. Renamed PAS to
+ PAU.
+
- The `pluggableauth` package has been deprecated. The `pas` module
provides a much more modular approach with many more capabilities.
Deleted: Zope3/trunk/package-includes/pas-configure.zcml
===================================================================
--- Zope3/trunk/package-includes/pas-configure.zcml 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/package-includes/pas-configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1 +0,0 @@
-<include package="zope.app.pas" />
\ No newline at end of file
Copied: Zope3/trunk/package-includes/pau-configure.zcml (from rev 28651, Zope3/trunk/package-includes/pas-configure.zcml)
===================================================================
--- Zope3/trunk/package-includes/pas-configure.zcml 2004-12-19 11:42:20 UTC (rev 28651)
+++ Zope3/trunk/package-includes/pau-configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -0,0 +1 @@
+<include package="zope.app.pau" />
\ No newline at end of file
Modified: Zope3/trunk/src/zope/app/exception/browser/tests/test_unauthorized.py
===================================================================
--- Zope3/trunk/src/zope/app/exception/browser/tests/test_unauthorized.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/exception/browser/tests/test_unauthorized.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -19,10 +19,11 @@
from zope.interface import implements
from zope.publisher.browser import TestRequest
from zope.app import zapi
-from zope.app.security.interfaces import IAuthenticationService, IPrincipal
+from zope.app.tests import ztapi
+from zope.app.security.interfaces import IAuthenticationUtility, IPrincipal
from zope.app.container.contained import contained
from zope.app.exception.browser.unauthorized import Unauthorized
-from zope.app.event.tests.placelesssetup import PlacelessSetup
+from zope.app.tests.placelesssetup import PlacelessSetup
class Unauthorized(Unauthorized):
"""Unusually done by ZCML."""
@@ -41,8 +42,8 @@
def getId(self):
return self.id
-class DummyAuthService(object):
- implements(IAuthenticationService) # this is a lie
+class DummyAuthUtility(object):
+ implements(IAuthenticationUtility) # this is a lie
def unauthorized(self, principal_id, request):
self.principal_id = principal_id
@@ -52,19 +53,17 @@
class DummyPrincipalSource(object):
pass
-class Test(TestCase, PlacelessSetup):
+class Test(PlacelessSetup, TestCase):
def setUp(self):
super(Test, self).setUp()
- self.temp = zapi.getService
- self.authservice = DummyAuthService()
- zapi.getService = lambda name: self.authservice
+ self.auth = DummyAuthUtility()
+ ztapi.provideUtility(IAuthenticationUtility, self.auth)
def tearDown(self):
- zapi.getService = self.temp
super(Test, self).tearDown()
- def test(self):
+ def testUnauthorized(self):
exception = Exception()
try:
raise exception
@@ -79,10 +78,10 @@
self.assertEqual(request.response.getStatus(), 403)
# Make sure the auth service was called
- self.failUnless(self.authservice.request is request)
- self.assertEqual(self.authservice.principal_id, 23)
+ self.failUnless(self.auth.request is request)
+ self.assertEqual(self.auth.principal_id, 23)
- def testPluggableAuthService(self):
+ def testPluggableAuthUtility(self):
exception = Exception()
try:
raise exception
@@ -98,8 +97,8 @@
self.assertEqual(request.response.getStatus(), 403)
# Make sure the auth service was called
- self.failUnless(self.authservice.request is request)
- self.assertEqual(self.authservice.principal_id, 23)
+ self.failUnless(self.auth.request is request)
+ self.assertEqual(self.auth.principal_id, 23)
def test_suite():
return makeSuite(Test)
Modified: Zope3/trunk/src/zope/app/exception/browser/unauthorized.py
===================================================================
--- Zope3/trunk/src/zope/app/exception/browser/unauthorized.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/exception/browser/unauthorized.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -18,7 +18,6 @@
__docformat__ = 'restructuredtext'
from zope.app import zapi
-from zope.app.security.interfaces import IAuthenticationService
class Unauthorized(object):
@@ -28,5 +27,5 @@
# challenge the user
self.request.response.setStatus(403)
principal = self.request.principal
- auth = zapi.getService(zapi.servicenames.Authentication)
+ auth = zapi.principals()
auth.unauthorized(principal.id, self.request)
Modified: Zope3/trunk/src/zope/app/homefolder/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/tests.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/homefolder/tests.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Pluggable Authentication Service Tests
+"""Homefolder Tests
$Id: tests.py 28311 2004-11-01 19:03:56Z jim $
"""
Copied: Zope3/trunk/src/zope/app/pau (from rev 28629, Zope3/trunk/src/zope/app/pas)
Deleted: Zope3/trunk/src/zope/app/pau/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/README.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/README.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,555 +0,0 @@
-================================
-Pluggable Authentication Service
-================================
-
-The Pluggable Authentication Service (PAS) provides a framework for
-authenticating principals and associating information with them. It
-uses a variety of different utilities, called plugins, and subscribers
-to get its work done.
-
-Authentication
-==============
-
-The primary job of an authentication service is to authenticate
-principals. Given a request object, the authentication service
-returns a principal object, if it can. The PAS does this in two
-steps:
-
-1. It determines a principal ID based on authentication credentials
- found in a request, and then
-
-2. It constructs a principal from the given ID, combining information
- from a number of sources.
-
-It uses plug-ins in both phases of its work. Plugins are named
-utilities that the service is configured to use in some order.
-
-In the first phase, the PAS iterates through a sequence of extractor
-plugins. From each plugin, it attempts to get a set of credentials.
-If it gets credentials, it iterates through a sequence of authentication
-plugins, trying to get a principal id for the given credentials. It
-continues this until it gets a principal id.
-
-Once it has a principal id, it begins the second phase. In the second
-phase, it iterates through a collection of principal-factory plugins until a
-plugin returns a principal object for given principal ID.
-
-When a factory creates a principal, it publishes a principal-created
-event. Subscribers to this event are responsible for adding data,
-especially groups, to the principal. Typically, if a subscriber adds
-data, it should also add corresponding interface declarations.
-
-Let's look at an example. We create a simple plugin that provides
-credential extraction:
-
- >>> import zope.interface
- >>> from zope.app.pas import interfaces
-
- >>> class MyExtractor:
- ...
- ... zope.interface.implements(interfaces.IExtractionPlugin)
- ...
- ... def extractCredentials(self, request):
- ... return request.get('credentials')
-
-We need to register this as a utility. Normally, we'd do this in
-ZCML. For the example here, we'll use the provideUtility function from
-`zope.app.tests.ztapi`:
-
- >>> from zope.app.tests.ztapi import provideUtility
- >>> provideUtility(interfaces.IExtractionPlugin, MyExtractor(), name='emy')
-
-Now we also create an authenticator plugin that knows about object 42:
-
- >>> class Auth42:
- ...
- ... zope.interface.implements(interfaces.IAuthenticationPlugin)
- ...
- ... def authenticateCredentials(self, credentials):
- ... if credentials == 42:
- ... return '42', {'domain': 42}
-
- >>> provideUtility(interfaces.IAuthenticationPlugin, Auth42(), name='a42')
-
-We provide a principal factory plugin:
-
- >>> class Principal:
- ...
- ... description = title = ''
- ...
- ... def __init__(self, id):
- ... self.id = id
- ...
- ... def __repr__(self):
- ... return 'Principal(%r, %r)' % (self.id, self.title)
-
- >>> from zope.event import notify
- >>> class PrincipalFactory:
- ...
- ... zope.interface.implements(interfaces.IPrincipalFactoryPlugin)
- ...
- ... def createAuthenticatedPrincipal(self, id, info, request):
- ... principal = Principal(id)
- ... notify(interfaces.AuthenticatedPrincipalCreated(
- ... principal, info, request))
- ... return principal
- ...
- ... def createFoundPrincipal(self, id, info):
- ... principal = Principal(id)
- ... notify(interfaces.FoundPrincipalCreated(principal, info))
- ... return principal
-
- >>> provideUtility(interfaces.IPrincipalFactoryPlugin, PrincipalFactory(),
- ... name='pf')
-
-Finally, we create a PAS instance:
-
- >>> from zope.app import pas
- >>> service = pas.LocalPAS()
-
-Now, we'll create a request and try to authenticate:
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest(credentials=42)
- >>> service.authenticate(request)
-
-We don't get anything. Why? Because we haven't configured the service
-to use our plugins. Let's fix that:
-
- >>> service.extractors = ('emy', )
- >>> service.authenticators = ('a42', )
- >>> service.factories = ('pf', )
- >>> principal = service.authenticate(request)
- >>> principal
- Principal('42', '')
-
-In addition to getting a principal, an IPASPrincipalCreated event will
-have been generated. We'll use an the testing event logging API to
-see that this is the case:
-
- >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
-
- >>> [event] = getEvents(interfaces.IAuthenticatedPrincipalCreated)
-
-The event's principal is set to the principal:
-
- >>> event.principal is principal
- True
-
-its info is set to the information returned by the authenticator:
-
- >>> event.info
- {'domain': 42}
-
-and it's request set to the request we created:
-
- >>> event.request is request
- True
-
-Normally, we provide subscribers to these events that add additional
-information to the principal. For examples, we'll add one that sets
-the title to a repr of the event info:
-
- >>> def add_info(event):
- ... event.principal.title = `event.info`
-
- >>> from zope.app.tests.ztapi import subscribe
- >>> subscribe([interfaces.IPASPrincipalCreated], None, add_info)
-
-Now, if we authenticate a principal, its title will be set:
-
- >>> service.authenticate(request)
- Principal('42', "{'domain': 42}")
-
-We can supply multiple plugins. For example, let's override our
-authentication plugin:
-
- >>> class AuthInt:
- ...
- ... zope.interface.implements(interfaces.IAuthenticationPlugin)
- ...
- ... def authenticateCredentials(self, credentials):
- ... if isinstance(credentials, int):
- ... return str(credentials), {'int': credentials}
-
- >>> provideUtility(interfaces.IAuthenticationPlugin, AuthInt(), name='aint')
-
-If we put it before the original authenticator:
-
- >>> service.authenticators = 'aint', 'a42'
-
-Then it will override the original:
-
- >>> service.authenticate(request)
- Principal('42', "{'int': 42}")
-
-But if we put it after, the original will be used:
-
- >>> service.authenticators = 'a42', 'aint'
- >>> service.authenticate(request)
- Principal('42', "{'domain': 42}")
-
-But we'll fall back to the new one:
-
- >>> request = TestRequest(credentials=1)
- >>> service.authenticate(request)
- Principal('1', "{'int': 1}")
-
-As with with authenticators, we can specify multiple extractors:
-
- >>> class OddExtractor:
- ...
- ... zope.interface.implements(interfaces.IExtractionPlugin)
- ...
- ... def extractCredentials(self, request):
- ... credentials = request.get('credentials')
- ... if isinstance(credentials, int) and (credentials%2):
- ... return 1
-
- >>> provideUtility(interfaces.IExtractionPlugin, OddExtractor(), name='eodd')
- >>> service.extractors = 'eodd', 'emy'
-
- >>> request = TestRequest(credentials=41)
- >>> service.authenticate(request)
- Principal('1', "{'int': 1}")
-
- >>> request = TestRequest(credentials=42)
- >>> service.authenticate(request)
- Principal('42', "{'domain': 42}")
-
-And we can specify multiple factories:
-
- >>> class OddPrincipal(Principal):
- ...
- ... def __repr__(self):
- ... return 'OddPrincipal(%r, %r)' % (self.id, self.title)
-
- >>> class OddFactory:
- ...
- ... zope.interface.implements(interfaces.IPrincipalFactoryPlugin)
- ...
- ... def createAuthenticatedPrincipal(self, id, info, request):
- ... i = info.get('int')
- ... if not (i and (i%2)):
- ... return None
- ... principal = OddPrincipal(id)
- ... notify(interfaces.AuthenticatedPrincipalCreated(
- ... principal, info, request))
- ... return principal
- ...
- ... def createFoundPrincipal(self, id, info):
- ... i = info.get('int')
- ... if not (i and (i%2)):
- ... return None
- ... principal = OddPrincipal(id)
- ... notify(interfaces.FoundPrincipalCreated(
- ... principal, info))
- ... return principal
-
- >>> provideUtility(interfaces.IPrincipalFactoryPlugin, OddFactory(),
- ... name='oddf')
-
- >>> service.factories = 'oddf', 'pf'
-
- >>> request = TestRequest(credentials=41)
- >>> service.authenticate(request)
- OddPrincipal('1', "{'int': 1}")
-
- >>> request = TestRequest(credentials=42)
- >>> service.authenticate(request)
- Principal('42', "{'domain': 42}")
-
-In this example, we used the supplemental information to get the
-integer credentials. It's common for factories to decide whether they
-should be used depending on supplemental information. Factories
-should not try to inspect the principal ids. Why? Because, as we'll
-see later, the PAS may modify ids before giving them to factories.
-Similarly, subscribers should use the supplemental information for any
-data they need.
-
-Get a principal given an id
-===========================
-
-We can ask the PAS for a principal, given an id.
-
-To do this, the PAS uses principal search plugins:
-
- >>> class Search42:
- ...
- ... zope.interface.implements(interfaces.IPrincipalSearchPlugin)
- ...
- ... def principalInfo(self, principal_id):
- ... if principal_id == '42':
- ... return {'domain': 42}
-
- >>> provideUtility(interfaces.IPrincipalSearchPlugin, Search42(),
- ... name='s42')
-
- >>> class IntSearch:
- ...
- ... zope.interface.implements(interfaces.IPrincipalSearchPlugin)
- ...
- ... def principalInfo(self, principal_id):
- ... try:
- ... i = int(principal_id)
- ... except ValueError:
- ... return None
- ... if (i >= 0 and i < 100):
- ... return {'int': i}
-
- >>> provideUtility(interfaces.IPrincipalSearchPlugin, IntSearch(),
- ... name='sint')
-
- >>> service.searchers = 's42', 'sint'
-
- >>> service.getPrincipal('41')
- OddPrincipal('41', "{'int': 41}")
-
-In addition to returning a principal, this will generate an event:
-
- >>> clearEvents()
- >>> service.getPrincipal('42')
- Principal('42', "{'domain': 42}")
-
- >>> [event] = getEvents(interfaces.IPASPrincipalCreated)
- >>> event.principal
- Principal('42', "{'domain': 42}")
-
- >>> event.info
- {'domain': 42}
-
-Our PAS will not find a principal with the ID '123'. Therefore it will
-delegate to the next service. To make sure that it's delegated, we put in place
-a fake service.
-
- >>> from zope.app.component.localservice import testingNextService
- >>> from zope.app.site.interfaces import ISiteManager
- >>> from zope.app import servicenames
-
- >>> class FakeService:
- ...
- ... zope.interface.implements(ISiteManager)
- ...
- ... lastGetPrincipalCall = lastUnauthorizedCall = None
- ...
- ... def getPrincipal(self, name):
- ... self.lastGetPrincipalCall = name
- ...
- ... def unauthorized(self, id, request):
- ... self.lastUnauthorizedCall = id
-
- >>> nextservice = FakeService()
- >>> testingNextService(service, nextservice, servicenames.Authentication)
-
- >>> service.getPrincipal('123')
- >>> '123' == nextservice.lastGetPrincipalCall
- True
-
-Issuing a challenge
-===================
-
-If the unauthorized method is called on the PAS, the PAS iterates
-through a sequence of challenge plugins calling their challenge
-methods until one returns True, indicating that a challenge was
-issued. (This is a simplification. See "Protocols" below.)
-
-Nothing will happen if there are no plugins registered.
-
- >>> service.unauthorized(42, request)
-
-However, our next service was asked:
-
- >>> 42 == nextservice.lastUnauthorizedCall
- True
-
-What happens if a plugin is registered depends on the plugin. Let's
-create a plugin that sets a response header:
-
- >>> class Challenge:
- ...
- ... zope.interface.implements(interfaces.IChallengePlugin)
- ...
- ... def challenge(self, requests, response):
- ... response.setHeader('X-Unauthorized', 'True')
- ... return True
-
- >>> provideUtility(interfaces.IChallengePlugin, Challenge(), name='c')
- >>> service.challengers = ('c', )
-
-Now if we call unauthorized:
-
- >>> service.unauthorized(42, request)
-
-the response `X-Unauthorized` is set:
-
- >>> request.response.getHeader('X-Unauthorized')
- 'True'
-
-How challenges work in Zope 3
------------------------------
-
-To understand how the challenge plugins work, it's helpful to
-understand how the unauthorized method of authenticaton services
-get called.
-
-If an 'Unauthorized' exception is raised and not caught by application
-code, then the following things happen:
-
-1. The current transaction is aborted.
-
-2. A view is looked up for the exception.
-
-3. The view gets the authentication service and calls it's
- 'unauthorized' method.
-
-4. The PAS will call its challenge plugins. If none return a value,
- then the PAS delegates to the next authentication service above it
- in the containment hierarchy, or to the global authentication
- service.
-
-5. The view sets the body of the response.
-
-Protocols
----------
-
-Sometimes, we want multiple challengers to work together. For
-example, the HTTP specification allows multiple challenges to be isued
-in a response. A challenge plugin can provide a `protocol`
-attribute. If multiple challenge plugins have the same protocol,
-then, if any of them are called and return True, then they will all be
-called. Let's look at an example. We'll define two challengers that
-add challenges to a X-Challenges headers:
-
- >>> class ColorChallenge:
- ... zope.interface.implements(interfaces.IChallengePlugin)
- ...
- ... protocol = 'bridge'
- ...
- ... def challenge(self, requests, response):
- ... challenge = response.getHeader('X-Challenge', '')
- ... response.setHeader('X-Challenge',
- ... challenge + 'favorite color? ')
- ... return True
-
- >>> provideUtility(interfaces.IChallengePlugin, ColorChallenge(), name='cc')
- >>> service.challengers = 'cc, ', 'c'
-
- >>> class BirdChallenge:
- ... zope.interface.implements(interfaces.IChallengePlugin)
- ...
- ... protocol = 'bridge'
- ...
- ... def challenge(self, requests, response):
- ... challenge = response.getHeader('X-Challenge', '')
- ... response.setHeader('X-Challenge',
- ... challenge + 'swallow air speed? ')
- ... return True
-
- >>> provideUtility(interfaces.IChallengePlugin, BirdChallenge(), name='bc')
- >>> service.challengers = 'cc', 'c', 'bc'
-
-Now if we call unauthorized:
-
- >>> request = TestRequest(credentials=42)
- >>> service.unauthorized(42, request)
-
-the response `X-Unauthorized` is not set:
-
- >>> request.response.getHeader('X-Unauthorized')
-
-But the X-Challenge header has been set by both of the new challengers
-with the bridge protocol:
-
- >>> request.response.getHeader('X-Challenge')
- 'favorite color? swallow air speed? '
-
-Of course, if we put the original challenge first:
-
- >>> service.challengers = 'c', 'cc', 'bc'
- >>> request = TestRequest(credentials=42)
- >>> service.unauthorized(42, request)
-
-We get 'X-Unauthorized' but not 'X-Challenge':
-
- >>> request.response.getHeader('X-Unauthorized')
- 'True'
- >>> request.response.getHeader('X-Challenge')
-
-Issuing challenges during authentication
-----------------------------------------
-
-During authentication, extraction and authentication plugins can raise
-an 'Unauthorized' exception to indicate that a challenge should be
-issued immediately. They might do this if the recognize partial
-credentials that pertain to them.
-
-PAS prefixes
-============
-
-Principal ids are required to be unique system wide. Plugins will
-often provide options for providing id prefixes, so that different
-sets of plugins provide unique ids within a PAS. If there are
-multiple PASs in a system, it's a good idea to give each PAS a
-unique prefix, so that principal ids from different PASs don't
-conflict. We can provide a prefix when a PAS is created:
-
- >>> service = pas.PAS('mypas_')
- >>> service.extractors = 'eodd', 'emy'
- >>> service.authenticators = 'a42', 'aint'
- >>> service.factories = 'oddf', 'pf'
- >>> service.searchers = 's42', 'sint'
-
-Now, we'll create a request and try to authenticate:
-
- >>> request = TestRequest(credentials=42)
- >>> principal = service.authenticate(request)
- >>> principal
- Principal('mypas_42', "{'domain': 42}")
-
-Note that now, our principal's id has the PAS prefix.
-
-We can still lookup a principal, as long as we supply the prefix:
-
- >>> service.getPrincipal('mypas_42')
- Principal('mypas_42', "{'domain': 42}")
-
- >>> service.getPrincipal('mypas_41')
- OddPrincipal('mypas_41', "{'int': 41}")
-
-Searching
-=========
-
-As their name suggests, search plugins provide searching support.
-We've already seen them used to get principals given principal
-ids. They're also used to find principals given search criteria.
-
-Different search plugins are likely to use very different search
-criteria. There are two approaches a plugin can use to support
-searching:
-
-- A plugin can provide IQuerySchemaSearch, in addition to
- `IPrincipalSearchPlugin`. In this case, the plugin provises a search
- method and a schema that describes the input to be provided to the
- search method.
-
-- For browser-based applications, the plugin can provide a browser
- view that provides
- `zope.app.form.browser.interfaces.ISourceQueryView`.
-
-PAS uses search plugins in a very simple way. It mearly implements
-`zope.schema.interfaces.ISourceQueriables`:
-
- >>> [id for (id, queriable) in service.getQueriables()]
- ['s42', 'sint']
- >>> [queriable.__class__.__name__
- ... for (id, queriable) in service.getQueriables()]
- ['Search42', 'IntSearch']
-
-Design Notes
-============
-
-- It is common for the same component to implement authentication and
- search or extraction and challenge. See
- `ISearchableAuthenticationPlugin` and
- `IExtractionAndChallengePlugin`.
-
Copied: Zope3/trunk/src/zope/app/pau/README.txt (from rev 28658, Zope3/trunk/src/zope/app/pas/README.txt)
===================================================================
--- Zope3/trunk/src/zope/app/pas/README.txt 2004-12-20 22:58:33 UTC (rev 28658)
+++ Zope3/trunk/src/zope/app/pau/README.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -0,0 +1,553 @@
+================================
+Pluggable Authentication Utility
+================================
+
+The Pluggable Authentication Utility (PAU) provides a framework for
+authenticating principals and associating information with them. It uses a
+variety of different utilities, called plugins, and subscribers to get its
+work done.
+
+Authentication
+==============
+
+The primary job of an authentication utility is to authenticate principals.
+Given a request object, the authentication utility returns a principal object,
+if it can. The PAU does this in two steps:
+
+1. It determines a principal ID based on authentication credentials found in a
+ request, and then
+
+2. It constructs a principal from the given ID, combining information from a
+ number of sources.
+
+It uses plug-ins in both phases of its work. Plugins are named utilities that
+the utility is configured to use in some order.
+
+In the first phase, the PAU iterates through a sequence of extractor plugins.
+From each plugin, it attempts to get a set of credentials. If it gets
+credentials, it iterates through a sequence of authentication plugins, trying
+to get a principal id for the given credentials. It continues this until it
+gets a principal id.
+
+Once it has a principal id, it begins the second phase. In the second phase,
+it iterates through a collection of principal-factory plugins until a plugin
+returns a principal object for given principal ID.
+
+When a factory creates a principal, it publishes a principal-created event.
+Subscribers to this event are responsible for adding data, especially groups,
+to the principal. Typically, if a subscriber adds data, it should also add
+corresponding interface declarations.
+
+Let's look at an example. We create a simple plugin that provides credential
+extraction:
+
+ >>> import zope.interface
+ >>> from zope.app.pau import interfaces
+
+ >>> class MyExtractor:
+ ...
+ ... zope.interface.implements(interfaces.IExtractionPlugin)
+ ...
+ ... def extractCredentials(self, request):
+ ... return request.get('credentials')
+
+We need to register this as a utility. Normally, we'd do this in ZCML. For the
+example here, we'll use the `provideUtility()` function from
+`zope.app.tests.ztapi`:
+
+ >>> from zope.app.tests.ztapi import provideUtility
+ >>> provideUtility(interfaces.IExtractionPlugin, MyExtractor(), name='emy')
+
+Now we also create an authenticator plugin that knows about object 42:
+
+ >>> class Auth42:
+ ...
+ ... zope.interface.implements(interfaces.IAuthenticationPlugin)
+ ...
+ ... def authenticateCredentials(self, credentials):
+ ... if credentials == 42:
+ ... return '42', {'domain': 42}
+
+ >>> provideUtility(interfaces.IAuthenticationPlugin, Auth42(), name='a42')
+
+We provide a principal factory plugin:
+
+ >>> class Principal:
+ ...
+ ... description = title = ''
+ ...
+ ... def __init__(self, id):
+ ... self.id = id
+ ...
+ ... def __repr__(self):
+ ... return 'Principal(%r, %r)' % (self.id, self.title)
+
+ >>> from zope.event import notify
+ >>> class PrincipalFactory:
+ ...
+ ... zope.interface.implements(interfaces.IPrincipalFactoryPlugin)
+ ...
+ ... def createAuthenticatedPrincipal(self, id, info, request):
+ ... principal = Principal(id)
+ ... notify(interfaces.AuthenticatedPrincipalCreated(
+ ... principal, info, request))
+ ... return principal
+ ...
+ ... def createFoundPrincipal(self, id, info):
+ ... principal = Principal(id)
+ ... notify(interfaces.FoundPrincipalCreated(principal, info))
+ ... return principal
+
+ >>> provideUtility(interfaces.IPrincipalFactoryPlugin, PrincipalFactory(),
+ ... name='pf')
+
+Finally, we create a PAU instance:
+
+ >>> from zope.app import pau
+ >>> auth = pau.LocalPAU()
+
+Now, we'll create a request and try to authenticate:
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest(credentials=42)
+ >>> auth.authenticate(request)
+
+We don't get anything. Why? Because we haven't configured the authentication
+utility to use our plugins. Let's fix that:
+
+ >>> auth.extractors = ('emy', )
+ >>> auth.authenticators = ('a42', )
+ >>> auth.factories = ('pf', )
+ >>> principal = auth.authenticate(request)
+ >>> principal
+ Principal('42', '')
+
+In addition to getting a principal, an `IPAUPrincipalCreated` event will
+have been generated. We'll use an the testing event logging API to
+see that this is the case:
+
+ >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+
+ >>> [event] = getEvents(interfaces.IAuthenticatedPrincipalCreated)
+
+The event's principal is set to the principal:
+
+ >>> event.principal is principal
+ True
+
+its info is set to the information returned by the authenticator:
+
+ >>> event.info
+ {'domain': 42}
+
+and it's request set to the request we created:
+
+ >>> event.request is request
+ True
+
+Normally, we provide subscribers to these events that add additional
+information to the principal. For examples, we'll add one that sets
+the title to a repr of the event info:
+
+ >>> def add_info(event):
+ ... event.principal.title = `event.info`
+
+ >>> from zope.app.tests.ztapi import subscribe
+ >>> subscribe([interfaces.IPAUPrincipalCreated], None, add_info)
+
+Now, if we authenticate a principal, its title will be set:
+
+ >>> auth.authenticate(request)
+ Principal('42', "{'domain': 42}")
+
+We can supply multiple plugins. For example, let's override our
+authentication plugin:
+
+ >>> class AuthInt:
+ ...
+ ... zope.interface.implements(interfaces.IAuthenticationPlugin)
+ ...
+ ... def authenticateCredentials(self, credentials):
+ ... if isinstance(credentials, int):
+ ... return str(credentials), {'int': credentials}
+
+ >>> provideUtility(interfaces.IAuthenticationPlugin, AuthInt(), name='aint')
+
+If we put it before the original authenticator:
+
+ >>> auth.authenticators = 'aint', 'a42'
+
+Then it will override the original:
+
+ >>> auth.authenticate(request)
+ Principal('42', "{'int': 42}")
+
+But if we put it after, the original will be used:
+
+ >>> auth.authenticators = 'a42', 'aint'
+ >>> auth.authenticate(request)
+ Principal('42', "{'domain': 42}")
+
+But we'll fall back to the new one:
+
+ >>> request = TestRequest(credentials=1)
+ >>> auth.authenticate(request)
+ Principal('1', "{'int': 1}")
+
+As with with authenticators, we can specify multiple extractors:
+
+ >>> class OddExtractor:
+ ...
+ ... zope.interface.implements(interfaces.IExtractionPlugin)
+ ...
+ ... def extractCredentials(self, request):
+ ... credentials = request.get('credentials')
+ ... if isinstance(credentials, int) and (credentials%2):
+ ... return 1
+
+ >>> provideUtility(interfaces.IExtractionPlugin, OddExtractor(), name='eodd')
+ >>> auth.extractors = 'eodd', 'emy'
+
+ >>> request = TestRequest(credentials=41)
+ >>> auth.authenticate(request)
+ Principal('1', "{'int': 1}")
+
+ >>> request = TestRequest(credentials=42)
+ >>> auth.authenticate(request)
+ Principal('42', "{'domain': 42}")
+
+And we can specify multiple factories:
+
+ >>> class OddPrincipal(Principal):
+ ...
+ ... def __repr__(self):
+ ... return 'OddPrincipal(%r, %r)' % (self.id, self.title)
+
+ >>> class OddFactory:
+ ...
+ ... zope.interface.implements(interfaces.IPrincipalFactoryPlugin)
+ ...
+ ... def createAuthenticatedPrincipal(self, id, info, request):
+ ... i = info.get('int')
+ ... if not (i and (i%2)):
+ ... return None
+ ... principal = OddPrincipal(id)
+ ... notify(interfaces.AuthenticatedPrincipalCreated(
+ ... principal, info, request))
+ ... return principal
+ ...
+ ... def createFoundPrincipal(self, id, info):
+ ... i = info.get('int')
+ ... if not (i and (i%2)):
+ ... return None
+ ... principal = OddPrincipal(id)
+ ... notify(interfaces.FoundPrincipalCreated(
+ ... principal, info))
+ ... return principal
+
+ >>> provideUtility(interfaces.IPrincipalFactoryPlugin, OddFactory(),
+ ... name='oddf')
+
+ >>> auth.factories = 'oddf', 'pf'
+
+ >>> request = TestRequest(credentials=41)
+ >>> auth.authenticate(request)
+ OddPrincipal('1', "{'int': 1}")
+
+ >>> request = TestRequest(credentials=42)
+ >>> auth.authenticate(request)
+ Principal('42', "{'domain': 42}")
+
+In this example, we used the supplemental information to get the
+integer credentials. It's common for factories to decide whether they
+should be used depending on supplemental information. Factories
+should not try to inspect the principal ids. Why? Because, as we'll
+see later, the PAU may modify ids before giving them to factories.
+Similarly, subscribers should use the supplemental information for any
+data they need.
+
+Get a principal given an id
+===========================
+
+We can ask the PAU for a principal, given an id.
+
+To do this, the PAU uses principal search plugins:
+
+ >>> class Search42:
+ ...
+ ... zope.interface.implements(interfaces.IPrincipalSearchPlugin)
+ ...
+ ... def principalInfo(self, principal_id):
+ ... if principal_id == '42':
+ ... return {'domain': 42}
+
+ >>> provideUtility(interfaces.IPrincipalSearchPlugin, Search42(),
+ ... name='s42')
+
+ >>> class IntSearch:
+ ...
+ ... zope.interface.implements(interfaces.IPrincipalSearchPlugin)
+ ...
+ ... def principalInfo(self, principal_id):
+ ... try:
+ ... i = int(principal_id)
+ ... except ValueError:
+ ... return None
+ ... if (i >= 0 and i < 100):
+ ... return {'int': i}
+
+ >>> provideUtility(interfaces.IPrincipalSearchPlugin, IntSearch(),
+ ... name='sint')
+
+ >>> auth.searchers = 's42', 'sint'
+
+ >>> auth.getPrincipal('41')
+ OddPrincipal('41', "{'int': 41}")
+
+In addition to returning a principal, this will generate an event:
+
+ >>> clearEvents()
+ >>> auth.getPrincipal('42')
+ Principal('42', "{'domain': 42}")
+
+ >>> [event] = getEvents(interfaces.IPAUPrincipalCreated)
+ >>> event.principal
+ Principal('42', "{'domain': 42}")
+
+ >>> event.info
+ {'domain': 42}
+
+Our PAU will not find a principal with the ID '123'. Therefore it will
+delegate to the next utility. To make sure that it's delegated, we put in place
+a fake utility.
+
+ >>> from zope.app.utility.utility import testingNextUtility
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
+
+ >>> class FakeAuthUtility:
+ ...
+ ... zope.interface.implements(IAuthenticationUtility)
+ ...
+ ... lastGetPrincipalCall = lastUnauthorizedCall = None
+ ...
+ ... def getPrincipal(self, name):
+ ... self.lastGetPrincipalCall = name
+ ...
+ ... def unauthorized(self, id, request):
+ ... self.lastUnauthorizedCall = id
+
+ >>> nextauth = FakeAuthUtility()
+ >>> testingNextUtility(auth, nextauth, IAuthenticationUtility)
+
+ >>> auth.getPrincipal('123')
+ >>> '123' == nextauth.lastGetPrincipalCall
+ True
+
+Issuing a challenge
+===================
+
+If the unauthorized method is called on the PAU, the PAU iterates
+through a sequence of challenge plugins calling their challenge
+methods until one returns True, indicating that a challenge was
+issued. (This is a simplification. See "Protocols" below.)
+
+Nothing will happen if there are no plugins registered.
+
+ >>> auth.unauthorized(42, request)
+
+However, our next utility was asked:
+
+ >>> 42 == nextauth.lastUnauthorizedCall
+ True
+
+What happens if a plugin is registered depends on the plugin. Let's
+create a plugin that sets a response header:
+
+ >>> class Challenge:
+ ...
+ ... zope.interface.implements(interfaces.IChallengePlugin)
+ ...
+ ... def challenge(self, requests, response):
+ ... response.setHeader('X-Unauthorized', 'True')
+ ... return True
+
+ >>> provideUtility(interfaces.IChallengePlugin, Challenge(), name='c')
+ >>> auth.challengers = ('c', )
+
+Now if we call unauthorized:
+
+ >>> auth.unauthorized(42, request)
+
+the response `X-Unauthorized` is set:
+
+ >>> request.response.getHeader('X-Unauthorized')
+ 'True'
+
+How challenges work in Zope 3
+-----------------------------
+
+To understand how the challenge plugins work, it's helpful to
+understand how the unauthorized method of authenticaton services
+get called.
+
+If an 'Unauthorized' exception is raised and not caught by application
+code, then the following things happen:
+
+1. The current transaction is aborted.
+
+2. A view is looked up for the exception.
+
+3. The view gets the authentication utility and calls it's
+ 'unauthorized' method.
+
+4. The PAU will call its challenge plugins. If none return a value,
+ then the PAU delegates to the next authentication utility above it
+ in the containment hierarchy, or to the global authentication
+ utility.
+
+5. The view sets the body of the response.
+
+Protocols
+---------
+
+Sometimes, we want multiple challengers to work together. For
+example, the HTTP specification allows multiple challenges to be isued
+in a response. A challenge plugin can provide a `protocol`
+attribute. If multiple challenge plugins have the same protocol,
+then, if any of them are called and return True, then they will all be
+called. Let's look at an example. We'll define two challengers that
+add challenges to a X-Challenges headers:
+
+ >>> class ColorChallenge:
+ ... zope.interface.implements(interfaces.IChallengePlugin)
+ ...
+ ... protocol = 'bridge'
+ ...
+ ... def challenge(self, requests, response):
+ ... challenge = response.getHeader('X-Challenge', '')
+ ... response.setHeader('X-Challenge',
+ ... challenge + 'favorite color? ')
+ ... return True
+
+ >>> provideUtility(interfaces.IChallengePlugin, ColorChallenge(), name='cc')
+ >>> auth.challengers = 'cc, ', 'c'
+
+ >>> class BirdChallenge:
+ ... zope.interface.implements(interfaces.IChallengePlugin)
+ ...
+ ... protocol = 'bridge'
+ ...
+ ... def challenge(self, requests, response):
+ ... challenge = response.getHeader('X-Challenge', '')
+ ... response.setHeader('X-Challenge',
+ ... challenge + 'swallow air speed? ')
+ ... return True
+
+ >>> provideUtility(interfaces.IChallengePlugin, BirdChallenge(), name='bc')
+ >>> auth.challengers = 'cc', 'c', 'bc'
+
+Now if we call unauthorized:
+
+ >>> request = TestRequest(credentials=42)
+ >>> auth.unauthorized(42, request)
+
+the response `X-Unauthorized` is not set:
+
+ >>> request.response.getHeader('X-Unauthorized')
+
+But the X-Challenge header has been set by both of the new challengers
+with the bridge protocol:
+
+ >>> request.response.getHeader('X-Challenge')
+ 'favorite color? swallow air speed? '
+
+Of course, if we put the original challenge first:
+
+ >>> auth.challengers = 'c', 'cc', 'bc'
+ >>> request = TestRequest(credentials=42)
+ >>> auth.unauthorized(42, request)
+
+We get 'X-Unauthorized' but not 'X-Challenge':
+
+ >>> request.response.getHeader('X-Unauthorized')
+ 'True'
+ >>> request.response.getHeader('X-Challenge')
+
+Issuing challenges during authentication
+----------------------------------------
+
+During authentication, extraction and authentication plugins can raise
+an 'Unauthorized' exception to indicate that a challenge should be
+issued immediately. They might do this if the recognize partial
+credentials that pertain to them.
+
+PAU prefixes
+============
+
+Principal ids are required to be unique system wide. Plugins will
+often provide options for providing id prefixes, so that different
+sets of plugins provide unique ids within a PAU. If there are
+multiple PAUs in a system, it's a good idea to give each PAU a
+unique prefix, so that principal ids from different PAUs don't
+conflict. We can provide a prefix when a PAU is created:
+
+ >>> auth = pau.PAU('mypas_')
+ >>> auth.extractors = 'eodd', 'emy'
+ >>> auth.authenticators = 'a42', 'aint'
+ >>> auth.factories = 'oddf', 'pf'
+ >>> auth.searchers = 's42', 'sint'
+
+Now, we'll create a request and try to authenticate:
+
+ >>> request = TestRequest(credentials=42)
+ >>> principal = auth.authenticate(request)
+ >>> principal
+ Principal('mypas_42', "{'domain': 42}")
+
+Note that now, our principal's id has the PAU prefix.
+
+We can still lookup a principal, as long as we supply the prefix:
+
+ >>> auth.getPrincipal('mypas_42')
+ Principal('mypas_42', "{'domain': 42}")
+
+ >>> auth.getPrincipal('mypas_41')
+ OddPrincipal('mypas_41', "{'int': 41}")
+
+Searching
+=========
+
+As their name suggests, search plugins provide searching support.
+We've already seen them used to get principals given principal
+ids. They're also used to find principals given search criteria.
+
+Different search plugins are likely to use very different search
+criteria. There are two approaches a plugin can use to support
+searching:
+
+- A plugin can provide IQuerySchemaSearch, in addition to
+ `IPrincipalSearchPlugin`. In this case, the plugin provises a search
+ method and a schema that describes the input to be provided to the
+ search method.
+
+- For browser-based applications, the plugin can provide a browser
+ view that provides
+ `zope.app.form.browser.interfaces.ISourceQueryView`.
+
+PAU uses search plugins in a very simple way. It mearly implements
+`zope.schema.interfaces.ISourceQueriables`:
+
+ >>> [id for (id, queriable) in auth.getQueriables()]
+ ['s42', 'sint']
+ >>> [queriable.__class__.__name__
+ ... for (id, queriable) in auth.getQueriables()]
+ ['Search42', 'IntSearch']
+
+Design Notes
+============
+
+- It is common for the same component to implement authentication and
+ search or extraction and challenge. See
+ `ISearchableAuthenticationPlugin` and
+ `IExtractionAndChallengePlugin`.
+
Modified: Zope3/trunk/src/zope/app/pau/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/__init__.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/__init__.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,10 +11,10 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Pluggable Autentication Service
+"""Pluggable Autentication Utility
$Id$
"""
import interfaces
-from zope.app.pas.pas import PAS, LocalPAS
+from zope.app.pau.pau import PAU, LocalPAU
Modified: Zope3/trunk/src/zope/app/pau/authenticationplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/authenticationplugins.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/authenticationplugins.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -45,9 +45,9 @@
<browser:addMenuItem
- title="SQL PAS Authentication Plugin"
- description="A SQL PAS Authentication Plugin"
- class="zope.app.pas.sql.SQLAuthenticationPlugin"
+ title="SQL PAU Authentication Plugin"
+ description="A SQL PAU Authentication Plugin"
+ class="zope.app.pau.sql.SQLAuthenticationPlugin"
permission="zope.ManageContent"
/>
Modified: Zope3/trunk/src/zope/app/pau/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/browser/configure.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browser/configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -20,8 +20,8 @@
<addMenuItem
title="Principal Folder"
- description="A PAS Persistent Authentication Plugin"
- class="zope.app.pas.principalfolder.PrincipalFolder"
+ description="A PAU Persistent Authentication Plugin"
+ class="zope.app.pau.principalfolder.PrincipalFolder"
permission="zope.ManageServices"
view="AddPrincipalFolder.html"
/>
@@ -81,38 +81,38 @@
<tool
interface="..interfaces.IAuthenticationPlugin"
- title="PAS Authentication Plugin"
- description="PAS Authentication Plugin"
+ title="PAU Authentication Plugin"
+ description="PAU Authentication Plugin"
/>
<tool
interface="..interfaces.IPrincipalSearchPlugin"
- title="PAS Search Plugin"
- description="PAS Search Plugin"
+ title="PAU Search Plugin"
+ description="PAU Search Plugin"
/>
<tool
interface="..interfaces.ISearchableAuthenticationPlugin"
- title="PAS Search and Authentication Plugin"
- description="PAS Search and Authentication Plugin"
+ title="PAU Search and Authentication Plugin"
+ description="PAU Search and Authentication Plugin"
/>
<tool
interface="..interfaces.IExtractionPlugin"
- title="PAS Extraction Plugin"
- description="PAS Extraction Plugin"
+ title="PAU Extraction Plugin"
+ description="PAU Extraction Plugin"
/>
<tool
interface="..interfaces.IChallengePlugin"
- title="PAS Challenge Plugin"
- description="PAS Challenge Plugin"
+ title="PAU Challenge Plugin"
+ description="PAU Challenge Plugin"
/>
<tool
interface="..interfaces.IExtractionAndChallengePlugin"
- title="PAS Credential Extraction and Challenge Plugin"
- description="PAS Credential Extraction and Challenge Plugin"
+ title="PAU Credential Extraction and Challenge Plugin"
+ description="PAU Credential Extraction and Challenge Plugin"
/>
<include file="groupfolder.zcml" />
@@ -120,15 +120,15 @@
<!-- Challengers -->
<addMenuItem
- title="PAS Custom Realm Basic Auth Challenge Plugin"
- description="A PAS Basic Auth Challenge Plugin"
+ title="PAU Custom Realm Basic Auth Challenge Plugin"
+ description="A PAU Basic Auth Challenge Plugin"
class="..httpplugins.HTTPBasicAuthChallenger"
permission="zope.ManageContent"
/>
<addMenuItem
title="Custom Form Session Challenge Plugin"
- description="A PAS Challenge Plugin"
+ description="A PAU Challenge Plugin"
class="..browserplugins.FormChallenger"
permission="zope.ManageServices"
/>
@@ -136,8 +136,8 @@
<!-- Extractors -->
<addMenuItem
- title="PAS Browser Session Extractor"
- description="A PAS Extraction Plugin"
+ title="PAU Browser Session Extractor"
+ description="A PAU Extraction Plugin"
class="..browserplugins.SessionExtractor"
permission="zope.ManageServices"
/>
Modified: Zope3/trunk/src/zope/app/pau/browser/groupfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/browser/groupfolder.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browser/groupfolder.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -3,9 +3,9 @@
Group folders are used to define groups. Before you can define
groups, you have to create a group folder and configure it in a
-pluggable authentication service (PAS). The group folder has to be
-registered with a PAS before defining any groups. This is because the
-groups folder needs to use the PAS to find all of the groups
+pluggable authentication service (PAU). The group folder has to be
+registered with a PAU before defining any groups. This is because the
+groups folder needs to use the PAU to find all of the groups
containing a given group so that it can check for group cycles. Not
all of a group's groups need to be defined in it's group folder. Other
groups folders or group-defining plugins could define groups for a
@@ -34,19 +34,19 @@
... Content-Type: multipart/form-data; boundary=---------------------------190685539214643056941988788830
... Referer: http://localhost:8081/++etc++site/AddISearchableAuthenticationPluginTool/AddPrincipalFolder.html=
...
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="field.prefix"
- ...
- ... users.
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ... users
- ... -----------------------------190685539214643056941988788830--
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="field.prefix"
+ ...
+ ... users.
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... users
+ ... -----------------------------190685539214643056941988788830--
... """)
HTTP/1.1 303 See Other
...
@@ -61,31 +61,31 @@
... Content-Length: 784
... Content-Type: multipart/form-data; boundary=---------------------------62010169718836874861388307181
...
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... bob
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Bob
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------62010169718836874861388307181
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------62010169718836874861388307181--
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... bob
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Bob
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------62010169718836874861388307181
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------62010169718836874861388307181--
... """)
HTTP/1.1 303 See Other
...
@@ -98,31 +98,31 @@
... Content-Length: 779
... Content-Type: multipart/form-data; boundary=---------------------------1501629520183211901834390790
...
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... bill
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Bill
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------1501629520183211901834390790
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------1501629520183211901834390790--
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... bill
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Bill
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------1501629520183211901834390790
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------1501629520183211901834390790--
... """)
HTTP/1.1 303 See Other
...
@@ -135,31 +135,31 @@
... Content-Length: 781
... Content-Type: multipart/form-data; boundary=---------------------------3362827831346173768318792608
...
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... betty
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Betty
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------3362827831346173768318792608
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------3362827831346173768318792608--
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... betty
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Betty
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------3362827831346173768318792608
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------3362827831346173768318792608--
... """)
HTTP/1.1 303 See Other
...
@@ -172,31 +172,31 @@
... Content-Length: 781
... Content-Type: multipart/form-data; boundary=---------------------------1771586876978613244952985501
...
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... sally
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Sally
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------1771586876978613244952985501
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------1771586876978613244952985501--
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... sally
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Sally
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------1771586876978613244952985501
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------1771586876978613244952985501--
... """)
HTTP/1.1 303 See Other
...
@@ -209,31 +209,31 @@
... Content-Length: 783
... Content-Type: multipart/form-data; boundary=---------------------------6406512534224572322062554722
...
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... george
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... George
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------6406512534224572322062554722
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------6406512534224572322062554722--
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... george
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... George
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------6406512534224572322062554722
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------6406512534224572322062554722--
... """)
HTTP/1.1 303 See Other
...
@@ -246,31 +246,31 @@
... Content-Length: 779
... Content-Type: multipart/form-data; boundary=---------------------------1596878616204415667781266350
...
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... mike
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Mike
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------1596878616204415667781266350
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------1596878616204415667781266350--
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... mike
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Mike
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------1596878616204415667781266350
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------1596878616204415667781266350--
... """)
HTTP/1.1 303 See Other
...
@@ -283,31 +283,31 @@
... Content-Length: 793
... Content-Type: multipart/form-data; boundary=---------------------------160587971417390263241080578782
...
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... mary
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Mary
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------160587971417390263241080578782
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------160587971417390263241080578782--
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... mary
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Mary
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------160587971417390263241080578782
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------160587971417390263241080578782--
... """)
HTTP/1.1 303 See Other
...
@@ -322,109 +322,145 @@
... Content-Length: 432
... Content-Type: multipart/form-data; boundary=---------------------------18984415031531709165482618952
...
- ... -----------------------------18984415031531709165482618952
- ... Content-Disposition: form-data; name="field.prefix"
- ...
- ... groups.
- ... -----------------------------18984415031531709165482618952
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------18984415031531709165482618952
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ... groups
- ... -----------------------------18984415031531709165482618952--
+ ... -----------------------------18984415031531709165482618952
+ ... Content-Disposition: form-data; name="field.prefix"
+ ...
+ ... groups.
+ ... -----------------------------18984415031531709165482618952
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------18984415031531709165482618952
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... groups
+ ... -----------------------------18984415031531709165482618952--
... """)
HTTP/1.1 303 See Other
...
Location: ../@@manageIPrincipalSearchPluginTool.html
...
-Now, before we can define any groups, we have to add a PAS:
+Now, before we can define any groups, we have to add and register a PAU:
>>> print http(r"""
- ... POST /++etc++site/default/AddService/action.html HTTP/1.1
- ... Authorization: Basic mgr:mgrpw
- ... Content-Length: 61
+ ... POST /++etc++site/default/@@contents.html HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 58
... Content-Type: application/x-www-form-urlencoded
+ ... Referer: http://localhost:8081/++etc++site/default/@@contents.html
...
- ... type_name=BrowserAdd__zope.app.pas.pas.LocalPAS&id=&add=+Add+""")
+ ... type_name=BrowserAdd__zope.app.pau.pau.LocalPAU&new_value=""")
HTTP/1.1 303 See Other
...
- Location: http://localhost/++etc++site/default/LocalPAS/@@registration.html
+
+ >>> print http(r"""
+ ... POST /++etc++site/default/LocalPAU/addRegistration.html HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 852
+ ... Content-Type: multipart/form-data; boundary=---------------------------1649392783947785437368129046
+ ... Referer: http://localhost:8081/++etc++site/default/LocalPAU/
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.name"
+ ...
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.interface"
+ ...
+ ... zope.app.security.interfaces.IAuthenticationUtility
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.interface-empty-marker"
+ ...
+ ... 1
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.permission"
+ ...
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.permission-empty-marker"
+ ...
+ ... 1
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------1649392783947785437368129046--
+ ... """)
+ HTTP/1.1 303 See Other
...
+
and configure it to use the principal folder and the groups folder:
>>> print http(r"""
- ... POST /++etc++site/default/LocalPAS/@@edit.html HTTP/1.1
+ ... POST /++etc++site/default/LocalPAU/@@edit.html HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-Length: 2073
... Content-Type: multipart/form-data; boundary=---------------------------18023914511159666166636904990
...
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.extractors.to"
- ...
- ... HTTP Basic
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.authenticators.to"
- ...
- ... users
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.challengers.to"
- ...
- ... No Challenge if Authenticated
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.challengers.to"
- ...
- ... Zope Realm HTTP Basic
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.factories.to"
- ...
- ... Default
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.searchers.to"
- ...
- ... users
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.searchers.to"
- ...
- ... groups
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Change
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.extractors"
- ...
- ... HTTP Basic
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.authenticators"
- ...
- ... users
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.challengers"
- ...
- ... No Challenge if Authenticated
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.challengers"
- ...
- ... Zope Realm HTTP Basic
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.factories"
- ...
- ... Default
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.searchers"
- ...
- ... users
- ... -----------------------------18023914511159666166636904990
- ... Content-Disposition: form-data; name="field.searchers"
- ...
- ... groups
- ... -----------------------------18023914511159666166636904990--
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.extractors.to"
+ ...
+ ... HTTP Basic
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.authenticators.to"
+ ...
+ ... users
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.challengers.to"
+ ...
+ ... No Challenge if Authenticated
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.challengers.to"
+ ...
+ ... Zope Realm HTTP Basic
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.factories.to"
+ ...
+ ... Default
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.searchers.to"
+ ...
+ ... users
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.searchers.to"
+ ...
+ ... groups
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Change
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.extractors"
+ ...
+ ... HTTP Basic
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.authenticators"
+ ...
+ ... users
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.challengers"
+ ...
+ ... No Challenge if Authenticated
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.challengers"
+ ...
+ ... Zope Realm HTTP Basic
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.factories"
+ ...
+ ... Default
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.searchers"
+ ...
+ ... users
+ ... -----------------------------18023914511159666166636904990
+ ... Content-Disposition: form-data; name="field.searchers"
+ ...
+ ... groups
+ ... -----------------------------18023914511159666166636904990--
... """)
HTTP/1.1 200 Ok
...
@@ -438,23 +474,23 @@
... Content-Length: 540
... Content-Type: multipart/form-data; boundary=---------------------------5412502961004181070544094984
...
- ... -----------------------------5412502961004181070544094984
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Admin
- ... -----------------------------5412502961004181070544094984
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------5412502961004181070544094984
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------5412502961004181070544094984
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------5412502961004181070544094984--
+ ... -----------------------------5412502961004181070544094984
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Admin
+ ... -----------------------------5412502961004181070544094984
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------5412502961004181070544094984
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------5412502961004181070544094984
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------5412502961004181070544094984--
... """)
HTTP/1.1 303 See Other
...
@@ -470,47 +506,47 @@
... Content-Type: multipart/form-data; boundary=---------------------------67523504021030130962010243745
... Referer: http://localhost:8081/++etc++site/tools/groups/1/@@edit.html
...
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Admin
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuMw__
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuNw__
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuNg__
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals.displayed"
- ...
- ... y
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search"
- ...
- ...
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search"
- ...
- ...
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="field.principals.MA__.query.searchstring"
- ...
- ...
- ... -----------------------------67523504021030130962010243745
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Change
- ... -----------------------------67523504021030130962010243745--
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Admin
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuMw__
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuNw__
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuNg__
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals.displayed"
+ ...
+ ... y
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search"
+ ...
+ ...
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search"
+ ...
+ ...
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="field.principals.MA__.query.searchstring"
+ ...
+ ...
+ ... -----------------------------67523504021030130962010243745
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Change
+ ... -----------------------------67523504021030130962010243745--
... """)
HTTP/1.1 200 Ok
...
@@ -523,23 +559,23 @@
... Content-Length: 556
... Content-Type: multipart/form-data; boundary=---------------------------14430301351028860873795053640
...
- ... -----------------------------14430301351028860873795053640
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Power Users
- ... -----------------------------14430301351028860873795053640
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------14430301351028860873795053640
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------14430301351028860873795053640
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ... power
- ... -----------------------------14430301351028860873795053640--
+ ... -----------------------------14430301351028860873795053640
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Power Users
+ ... -----------------------------14430301351028860873795053640
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------14430301351028860873795053640
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------14430301351028860873795053640
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... power
+ ... -----------------------------14430301351028860873795053640--
... """)
HTTP/1.1 303 See Other
...
@@ -554,55 +590,55 @@
... Content-Length: 1708
... Content-Type: multipart/form-data; boundary=---------------------------46600477014278930691159535998
...
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Power Users
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuMw__
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuMg__
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuMQ__
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuNQ__
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals:list"
- ...
- ... dXNlcnMuNw__
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals.displayed"
- ...
- ... y
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search"
- ...
- ...
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search"
- ...
- ...
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="field.principals.MA__.query.searchstring"
- ...
- ...
- ... -----------------------------46600477014278930691159535998
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Change
- ... -----------------------------46600477014278930691159535998--
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Power Users
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuMw__
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuMg__
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuMQ__
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuNQ__
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals:list"
+ ...
+ ... dXNlcnMuNw__
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals.displayed"
+ ...
+ ... y
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals.MC51c2Vycw__.query.field.search"
+ ...
+ ...
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals.MC5ncm91cHM_.query.field.search"
+ ...
+ ...
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="field.principals.MA__.query.searchstring"
+ ...
+ ...
+ ... -----------------------------46600477014278930691159535998
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Change
+ ... -----------------------------46600477014278930691159535998--
... """)
HTTP/1.1 200 Ok
...
@@ -614,7 +650,7 @@
>>> from zope.app.component.hooks import setSite
>>> setSite(getRootFolder())
-and we'll get the PAS:
+and we'll get the PAU:
>>> from zope.app import zapi
>>> principals = zapi.principals()
Modified: Zope3/trunk/src/zope/app/pau/browser/principalfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/browser/principalfolder.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browser/principalfolder.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,10 +1,10 @@
Using Principal Folders
=======================
-Principal folders are PAS plugins that manage principal information,
+Principal folders are PAU plugins that manage principal information,
especially authentication credentials. To use a principal folder, you
need to create a principal folder in a site management folder and then
-configure it in a PAS. Let's look at an example, in which we'll
+configure it in a PAU. Let's look at an example, in which we'll
define a new manager named Bob. Initially, attempts to log in as Bob
fail:
@@ -37,19 +37,19 @@
... Content-Type: multipart/form-data; boundary=---------------------------190685539214643056941988788830
... Referer: http://localhost:8081/++etc++site/AddISearchableAuthenticationPluginTool/AddPrincipalFolder.html=
...
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="field.prefix"
- ...
- ... users.
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------190685539214643056941988788830
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ... users
- ... -----------------------------190685539214643056941988788830--
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="field.prefix"
+ ...
+ ... users.
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------190685539214643056941988788830
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... users
+ ... -----------------------------190685539214643056941988788830--
... """)
HTTP/1.1 303 See Other
...
@@ -80,31 +80,31 @@
... Content-Type: multipart/form-data; boundary=---------------------------7243003661505678908829226317
... Referer: http://localhost:8081/++etc++site/tools/users/+/AddPrincipalInformation.html=
...
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="field.login"
- ...
- ... bob
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="field.password"
- ...
- ... 123
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="field.title"
- ...
- ... Bob
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="field.description"
- ...
- ...
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Add
- ... -----------------------------7243003661505678908829226317
- ... Content-Disposition: form-data; name="add_input_name"
- ...
- ...
- ... -----------------------------7243003661505678908829226317--
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="field.login"
+ ...
+ ... bob
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="field.password"
+ ...
+ ... 123
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... Bob
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ...
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------7243003661505678908829226317
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ...
+ ... -----------------------------7243003661505678908829226317--
... """)
HTTP/1.1 303 See Other
...
@@ -114,85 +114,118 @@
Note that we didn't pick a name. The name, together with the folder
prefix. If we don't choose a name, a numeric id is chosen.
-Now we have a principal folder with a principal. We need to create a
-pluggable authentication service:
+Now we have a principal folder with a principal. We need to create and
+register a pluggable authentication utility:
-
>>> print http(r"""
- ... POST /++etc++site/default/AddService/action.html HTTP/1.1
- ... Authorization: Basic mgr:mgrpw
- ... Content-Length: 61
+ ... POST /++etc++site/default/@@contents.html HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 58
... Content-Type: application/x-www-form-urlencoded
- ... Referer: http://localhost:8081/++etc++site/default/AddService
+ ... Referer: http://localhost:8081/++etc++site/default/@@contents.html
...
- ... type_name=BrowserAdd__zope.app.pas.pas.LocalPAS&id=&add=+Add+""")
+ ... type_name=BrowserAdd__zope.app.pau.pau.LocalPAU&new_value=""")
HTTP/1.1 303 See Other
...
- Location: http://localhost/++etc++site/default/LocalPAS/@@registration.html
+
+ >>> print http(r"""
+ ... POST /++etc++site/default/LocalPAU/addRegistration.html HTTP/1.1
+ ... Authorization: Basic bWdyOm1ncnB3
+ ... Content-Length: 852
+ ... Content-Type: multipart/form-data; boundary=---------------------------1649392783947785437368129046
+ ... Referer: http://localhost:8081/++etc++site/default/LocalPAU/
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.name"
+ ...
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.interface"
+ ...
+ ... zope.app.security.interfaces.IAuthenticationUtility
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.interface-empty-marker"
+ ...
+ ... 1
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.permission"
+ ...
+ ...
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="field.permission-empty-marker"
+ ...
+ ... 1
+ ... -----------------------------1649392783947785437368129046
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------1649392783947785437368129046--
+ ... """)
+ HTTP/1.1 303 See Other
...
and configure it to use the principal folder:
>>> print http(r"""
- ... POST /++etc++site/default/LocalPAS/@@edit.html HTTP/1.1
+ ... POST /++etc++site/default/LocalPAU/@@edit.html HTTP/1.1
... Authorization: Basic mgr:mgrpw
... Content-Length: 1818
... Content-Type: multipart/form-data; boundary=---------------------------11831623361211414588608810327
- ... Referer: http://localhost:8081/++etc++site/default/LocalPAS/@@edit.html
+ ... Referer: http://localhost:8081/++etc++site/default/LocalPAU/@@edit.html
...
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.extractors.to"
- ...
- ... HTTP Basic
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.authenticators.to"
- ...
- ... users
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.challengers.to"
- ...
- ... No Challenge if Authenticated
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.challengers.to"
- ...
- ... Zope Realm HTTP Basic
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.factories.to"
- ...
- ... Default
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.searchers.to"
- ...
- ... users
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
- ...
- ... Change
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.extractors"
- ...
- ... HTTP Basic
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.authenticators"
- ...
- ... users
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.challengers"
- ...
- ... No Challenge if Authenticated
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.challengers"
- ...
- ... Zope Realm HTTP Basic
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.factories"
- ...
- ... Default
- ... -----------------------------11831623361211414588608810327
- ... Content-Disposition: form-data; name="field.searchers"
- ...
- ... users
- ... -----------------------------11831623361211414588608810327--
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.extractors.to"
+ ...
+ ... HTTP Basic
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.authenticators.to"
+ ...
+ ... users
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.challengers.to"
+ ...
+ ... No Challenge if Authenticated
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.challengers.to"
+ ...
+ ... Zope Realm HTTP Basic
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.factories.to"
+ ...
+ ... Default
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.searchers.to"
+ ...
+ ... users
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Change
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.extractors"
+ ...
+ ... HTTP Basic
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.authenticators"
+ ...
+ ... users
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.challengers"
+ ...
+ ... No Challenge if Authenticated
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.challengers"
+ ...
+ ... Zope Realm HTTP Basic
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.factories"
+ ...
+ ... Default
+ ... -----------------------------11831623361211414588608810327
+ ... Content-Disposition: form-data; name="field.searchers"
+ ...
+ ... users
+ ... -----------------------------11831623361211414588608810327--
... """)
HTTP/1.1 200 Ok
...
Modified: Zope3/trunk/src/zope/app/pau/browser/schemasearch.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/browser/schemasearch.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browser/schemasearch.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -20,7 +20,7 @@
from zope.interface import implements
from zope.i18n import translate
from zope.schema import getFieldsInOrder
-from zope.app.pas.interfaces import IQuerySchemaSearch
+from zope.app.pau.interfaces import IQuerySchemaSearch
from zope.app.form.utility import setUpWidgets, getWidgetsData
from zope.app.form.interfaces import IInputWidget
from zope.app.form.browser.interfaces import ISourceQueryView
Modified: Zope3/trunk/src/zope/app/pau/browser/schemasearch.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/browser/schemasearch.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browser/schemasearch.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -30,7 +30,7 @@
then we can get a view:
- >>> from zope.app.pas.browser.schemasearch import QuerySchemaSearchView
+ >>> from zope.app.pau.browser.schemasearch import QuerySchemaSearchView
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> view = QuerySchemaSearchView(MySearchPlugin(), request)
Modified: Zope3/trunk/src/zope/app/pau/browserplugins.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/browserplugins.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/browserplugins.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -28,7 +28,7 @@
import transaction
from urllib import urlencode
-from zope.app.pas.interfaces import IExtractionPlugin, IChallengePlugin
+from zope.app.pau.interfaces import IExtractionPlugin, IChallengePlugin
class ISessionCredentials(Interface):
@@ -119,7 +119,7 @@
>>> request = TestRequest(authrequest='logout')
>>> se.extractCredentials(request)
- >>> Session(request)['zope.app.pas.browserplugins']['credentials']
+ >>> Session(request)['zope.app.pau.browserplugins']['credentials']
"""
implements(IExtractionPlugin)
@@ -127,7 +127,7 @@
""" return credentials from session, request or None """
#if not credentials:
# check for form data
- sessionData = ISession(request)['zope.app.pas.browserplugins']
+ sessionData = ISession(request)['zope.app.pau.browserplugins']
login = request.get('login', None)
password = request.get('password', None)
if login and password:
Deleted: Zope3/trunk/src/zope/app/pau/challengeplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/challengeplugins.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/challengeplugins.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,47 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- i18n_domain="zope">
-
-
- <!-- Default preconfigured basic auth -->
- <utility
- name="Zope Realm HTTP Basic"
- factory=".httpplugins.HTTPBasicAuthChallenger"
- provides=".interfaces.IChallengePlugin"
- />
-
- <!-- Locally custom-configured basic auth -->
- <localUtility class=".httpplugins.HTTPBasicAuthChallenger">
-
- <require
- permission="zope.ManageServices"
- interface=".httpplugins.IHTTPBasicAuthRealm"
- set_schema=".httpplugins.IHTTPBasicAuthRealm" />
-
- </localUtility>
-
- <utility
- name="No Challenge if Authenticated"
- factory=".generic.AlreadyAuthenticatedUserChallenger"
- provides=".interfaces.IChallengePlugin"
- />
-
-
- <utility
- name="Rediect to loginForm.html"
- factory=".browserplugins.FormChallenger"
- provides=".interfaces.IChallengePlugin"
- />
-
- <!-- Configure where to redirect to -->
- <localUtility class=".browserplugins.FormChallenger">
-
- <require
- permission="zope.ManageServices"
- interface=".browserplugins.IFormChallengerLoginPageName"
- set_schema=".browserplugins.IFormChallengerLoginPageName" />
-
- </localUtility>
-
-</configure>
Copied: Zope3/trunk/src/zope/app/pau/challengeplugins.zcml (from rev 28658, Zope3/trunk/src/zope/app/pas/challengeplugins.zcml)
Modified: Zope3/trunk/src/zope/app/pau/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/configure.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -6,30 +6,26 @@
<interface interface=".interfaces.IPrincipalSearchPlugin" />
- <localService class=".LocalPAS">
+ <localUtility class=".LocalPAU">
<require
permission="zope.ManageServices"
- interface="zope.app.site.interfaces.ISimpleService"
+ interface=".pau.IPAU"
+ set_schema=".pau.IPAU"
/>
- <require
- permission="zope.ManageServices"
- interface=".pas.IPAS"
- set_schema=".pas.IPAS"
- />
- </localService>
+ </localUtility>
<interface interface=".interfaces.IPrincipalSearchPlugin" />
<browser:addMenuItem
- class=".pas.LocalPAS"
- title="Pluggable Authentication Service"
- description="New-style pluggable authentication service"
+ class=".pau.LocalPAU"
+ title="Pluggable Authentication Utility"
+ description="New-style pluggable authentication utility"
permission="zope.ManageServices"
/>
<browser:editform
- schema=".pas.IPAS"
- label="Edit Pluggable Authentication Service"
+ schema=".pau.IPAU"
+ label="Edit Pluggable Authentication Utility"
name="edit.html"
menu="zmi_views" title="Edit"
permission="zope.ManageServices" />
@@ -37,35 +33,35 @@
<vocabulary
name="ExtractionPlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
- interface="zope.app.pas.interfaces.IExtractionPlugin"
+ interface="zope.app.pau.interfaces.IExtractionPlugin"
nameOnly="True"
/>
<vocabulary
name="AuthenticationPlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
- interface="zope.app.pas.interfaces.IAuthenticationPlugin"
+ interface="zope.app.pau.interfaces.IAuthenticationPlugin"
nameOnly="True"
/>
<vocabulary
name="ChallengePlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
- interface="zope.app.pas.interfaces.IChallengePlugin"
+ interface="zope.app.pau.interfaces.IChallengePlugin"
nameOnly="True"
/>
<vocabulary
name="PrincipalFactoryPlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
- interface="zope.app.pas.interfaces.IPrincipalFactoryPlugin"
+ interface="zope.app.pau.interfaces.IPrincipalFactoryPlugin"
nameOnly="True"
/>
<vocabulary
name="PrincipalSearchPlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
- interface="zope.app.pas.interfaces.IPrincipalSearchPlugin"
+ interface="zope.app.pau.interfaces.IPrincipalSearchPlugin"
nameOnly="True"
/>
Modified: Zope3/trunk/src/zope/app/pau/groupfolder.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/groupfolder.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/groupfolder.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -33,8 +33,8 @@
import zope.app.container.constraints
from zope.app.container.interfaces import IContained, IContainer
from zope.app.i18n import ZopeMessageIDFactory as _
-from zope.app.pas.interfaces import IAuthenticatedPrincipalCreated
-from zope.app.pas.interfaces import IQuerySchemaSearch, IPrincipalSearchPlugin
+from zope.app.pau.interfaces import IAuthenticatedPrincipalCreated
+from zope.app.pau.interfaces import IQuerySchemaSearch, IPrincipalSearchPlugin
import zope.app.security.vocabulary
class IGroupInformation(zope.interface.Interface):
Modified: Zope3/trunk/src/zope/app/pau/groupfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/groupfolder.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/groupfolder.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -9,10 +9,10 @@
Group folders contain group-information objects that contain group
information. We create group information using the `GroupInformation` class:
- >>> import zope.app.pas.groupfolder
- >>> g1 = zope.app.pas.groupfolder.GroupInformation("Group 1")
+ >>> import zope.app.pau.groupfolder
+ >>> g1 = zope.app.pau.groupfolder.GroupInformation("Group 1")
- >>> groups = zope.app.pas.groupfolder.GroupFolder('group.')
+ >>> groups = zope.app.pau.groupfolder.GroupFolder('group.')
>>> groups['g1'] = g1
Groups are defined with respect to an authentication service. Groups
@@ -23,8 +23,8 @@
we'll create a sample authentication service:
>>> import zope.interface
- >>> from zope.app.security.interfaces import IAuthenticationService
- >>> from zope.app.pas.groupfolder import setGroupsForPrincipal
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
+ >>> from zope.app.pau.groupfolder import setGroupsForPrincipal
>>> class Principal:
... def __init__(self, id, title, description):
@@ -37,7 +37,7 @@
>>> class Principals:
...
- ... zope.interface.implements(IAuthenticationService)
+ ... zope.interface.implements(IAuthenticationUtility)
...
... def __init__(self, groups):
... self.principals = {
@@ -58,21 +58,21 @@
This class doesn't really implement the fill `IAuthenticationService`
interface, but it implements the `getPrincipal` method used by groups.
-It works very much like PAS. It creates principals on demand. It
+It works very much like PAU. It creates principals on demand. It
calls `setGroupsForPrincipal`, which is normally called as an event
subscriber, when principals are created. In order for
`setGroupsForPrincipal` to find out group folder, we have to register
it as a utility:
>>> from zope.app.tests import ztapi
- >>> ztapi.provideUtility(zope.app.pas.groupfolder.IGroupFolder,
+ >>> ztapi.provideUtility(zope.app.pau.groupfolder.IGroupFolder,
... groups)
The authentication service has a very simple implementation. It has a
`principals` dictionary and a groups folder.
>>> principals = Principals(groups)
- >>> ztapi.provideService('Authentication', principals)
+ >>> ztapi.provideUtility(IAuthenticationUtility, principals)
Now we can set the principals on the group:
@@ -115,7 +115,7 @@
Groups can contain groups:
- >>> g2 = zope.app.pas.groupfolder.GroupInformation("Group Two")
+ >>> g2 = zope.app.pau.groupfolder.GroupInformation("Group Two")
>>> groups['G2'] = g2
>>> g2.principals = ['group.G1']
@@ -131,18 +131,18 @@
They need not be hierarchical:
- >>> ga = zope.app.pas.groupfolder.GroupInformation("Group A")
+ >>> ga = zope.app.pau.groupfolder.GroupInformation("Group A")
>>> groups['GA'] = ga
- >>> gb = zope.app.pas.groupfolder.GroupInformation("Group B")
+ >>> gb = zope.app.pau.groupfolder.GroupInformation("Group B")
>>> groups['GB'] = gb
>>> gb.principals = ['group.GA']
- >>> gc = zope.app.pas.groupfolder.GroupInformation("Group C")
+ >>> gc = zope.app.pau.groupfolder.GroupInformation("Group C")
>>> groups['GC'] = gc
>>> gc.principals = ['group.GA']
- >>> gd = zope.app.pas.groupfolder.GroupInformation("Group D")
+ >>> gd = zope.app.pau.groupfolder.GroupInformation("Group D")
>>> groups['GD'] = gd
>>> gd.principals = ['group.GA', 'group.GB']
Modified: Zope3/trunk/src/zope/app/pau/groupfolder.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/groupfolder.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/groupfolder.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -19,7 +19,7 @@
<subscriber
factory=".groupfolder.setGroupsForPrincipal"
- for="zope.app.pas.interfaces.IPASPrincipalCreated"
+ for="zope.app.pau.interfaces.IPAUPrincipalCreated"
/>
<localUtility class=".groupfolder.GroupFolder">
Modified: Zope3/trunk/src/zope/app/pau/idpicker.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/idpicker.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/idpicker.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -4,7 +4,7 @@
The Id pickler is a variation on the name chooser that picks numeric
ids when no name is given.
- >>> from zope.app.pas.idpicker import IdPicker
+ >>> from zope.app.pau.idpicker import IdPicker
>>> IdPicker({}).chooseName('', None)
u'1'
Modified: Zope3/trunk/src/zope/app/pau/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/interfaces.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/interfaces.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Pluggable Authentication Service Interfaces
+"""Pluggable Authentication Utility Interfaces
$Id$
"""
@@ -20,10 +20,10 @@
import zope.interface
import zope.schema
-class IPASPrincipalCreated(zope.interface.Interface):
- """A PAS principal object has been created
+class IPAUPrincipalCreated(zope.interface.Interface):
+ """A PAU principal object has been created
- This event is generated when a transient PAS principal has been created.
+ This event is generated when a transient PAU principal has been created.
"""
principal = zope.interface.Attribute("The principal that was created")
@@ -36,7 +36,7 @@
),
)
-class IAuthenticatedPrincipalCreated(IPASPrincipalCreated):
+class IAuthenticatedPrincipalCreated(IPAUPrincipalCreated):
"""An authenticated principal object has been created
This event is generated when a principal has been created by
@@ -56,7 +56,7 @@
self.info = info
self.request = request
-class IFoundPrincipalCreated(IPASPrincipalCreated):
+class IFoundPrincipalCreated(IPAUPrincipalCreated):
"""Event indicating that a principal was created based on a search
"""
@@ -69,18 +69,18 @@
self.info = info
class IPlugin(zope.interface.Interface):
- """Provide functionality to be pluged into a PAS
+ """Provide functionality to be pluged into a PAU
"""
class IPrincipalIdAwarePlugin(IPlugin):
"""Principal-Id aware plugin
A requirements of plugins that deal with principal ids is that
- principal ids must be unique within a PAS. A PAS manager may want
+ principal ids must be unique within a PAU. A PAU manager may want
to use plugins to support multiple principal sources. If the ids
from the various principal sources overlap, there needs to be some
way to disambiguate them. For this reason, it's a good idea for
- id-aware plugins to provide a way for a PAS manager to configure
+ id-aware plugins to provide a way for a PAU manager to configure
an id prefix or some other mechanism to make sure that
principal-ids from different domains don't overlap.
"""
Deleted: Zope3/trunk/src/zope/app/pau/pas.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/pas.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/pas.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,176 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 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.
-#
-##############################################################################
-"""Pluggable authentication service implementation
-
-$Id$
-"""
-
-from zope.event import notify
-import zope.interface
-import zope.schema
-from persistent import Persistent
-
-from zope.schema.interfaces import ISourceQueriables
-
-from zope.app import zapi
-
-from zope.app.security.interfaces import IAuthenticationService
-from zope.app.servicenames import Authentication
-from zope.app.component.localservice import queryNextService
-from zope.app.container.contained import Contained
-from zope.app.site.interfaces import ISimpleService
-from zope.app.location.interfaces import ILocation
-
-from zope.app.pas import interfaces
-from zope.app.pas.interfaces import IExtractionPlugin
-from zope.app.pas.interfaces import IAuthenticationPlugin
-from zope.app.pas.interfaces import IChallengePlugin
-from zope.app.pas.interfaces import IPrincipalFactoryPlugin
-from zope.app.pas.interfaces import IPrincipalSearchPlugin
-
-
-class IPAS(zope.interface.Interface):
- """Pluggable Authentication Service
- """
-
- extractors = zope.schema.List(
- title=u"Credential Extractors",
- value_type = zope.schema.Choice(vocabulary='ExtractionPlugins'),
- default=[],
- )
-
- authenticators = zope.schema.List(
- title=u"Authenticators",
- value_type = zope.schema.Choice(vocabulary='AuthenticationPlugins'),
- default=[],
- )
-
- challengers = zope.schema.List(
- title=u"Challengers",
- value_type = zope.schema.Choice(vocabulary='ChallengePlugins'),
- default=[],
- )
-
- factories = zope.schema.List(
- title=u"Principal Factories",
- value_type = zope.schema.Choice(vocabulary='PrincipalFactoryPlugins'),
- default=[],
- )
-
- searchers = zope.schema.List(
- title=u"Search Plugins",
- value_type = zope.schema.Choice(vocabulary='PrincipalSearchPlugins'),
- default=[],
- )
-
-class PAS:
-
- zope.interface.implements(IPAS, IAuthenticationService, ISourceQueriables)
-
- authenticators = extractors = challengers = factories = searchers = ()
-
- def __init__(self, prefix=''):
- self.prefix = prefix
-
- def authenticate(self, request):
- authenticators = [zapi.queryUtility(IAuthenticationPlugin, name)
- for name in self.authenticators]
- for extractor in self.extractors:
- extractor = zapi.queryUtility(IExtractionPlugin, extractor)
- if extractor is None:
- continue
- credentials = extractor.extractCredentials(request)
- for authenticator in authenticators:
- if authenticator is None:
- continue
- authenticated = authenticator.authenticateCredentials(
- credentials)
- if authenticated is None:
- continue
-
- id, info = authenticated
- return self._create('createAuthenticatedPrincipal',
- self.prefix+id, info, request)
- return None
-
- def _create(self, meth, *args):
- # We got some data, lets create a user
- for factory in self.factories:
- factory = zapi.queryUtility(IPrincipalFactoryPlugin,
- factory)
- if factory is None:
- continue
-
- principal = getattr(factory, meth)(*args)
- if principal is None:
- continue
-
- return principal
-
- def getPrincipal(self, id):
- if not id.startswith(self.prefix):
- return self._delegate('getPrincipal', id)
- id = id[len(self.prefix):]
-
- for searcher in self.searchers:
- searcher = zapi.queryUtility(IPrincipalSearchPlugin, searcher)
- if searcher is None:
- continue
-
- info = searcher.principalInfo(id)
- if info is None:
- continue
-
- return self._create('createFoundPrincipal', self.prefix+id, info)
-
- return self._delegate('getPrincipal', self.prefix+id)
-
- def getQueriables(self):
- for searcher_id in self.searchers:
- searcher = zapi.queryUtility(IPrincipalSearchPlugin, searcher_id)
- yield searcher_id, searcher
-
-
- def unauthenticatedPrincipal(self):
- return None
-
- def unauthorized(self, id, request):
- protocol = None
-
- for challenger in self.challengers:
- challenger = zapi.queryUtility(IChallengePlugin, challenger)
- if challenger is None:
- continue # skip non-existant challengers
-
- challenger_protocol = getattr(challenger, 'protocol', None)
- if protocol is None or challenger_protocol == protocol:
- if challenger.challenge(request, request.response):
- if challenger_protocol is None:
- return
- elif protocol is None:
- protocol = challenger_protocol
-
- if protocol is None:
- self._delegate('unauthorized', id, request)
-
- def _delegate(self, meth, *args):
- # delegate to next AS
- next = queryNextService(self, Authentication, None)
- if next is None:
- return None
- return getattr(next, meth)(*args)
-
-
-class LocalPAS(PAS, Persistent, Contained):
- zope.interface.implements(IPAS, ILocation, ISimpleService)
Copied: Zope3/trunk/src/zope/app/pau/pau.py (from rev 28629, Zope3/trunk/src/zope/app/pas/pas.py)
===================================================================
--- Zope3/trunk/src/zope/app/pas/pas.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/pau.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -0,0 +1,175 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Pluggable Authentication Utility implementation
+
+$Id$
+"""
+
+from zope.event import notify
+import zope.interface
+import zope.schema
+from persistent import Persistent
+
+from zope.schema.interfaces import ISourceQueriables
+
+from zope.app import zapi
+
+from zope.app.security.interfaces import IAuthenticationUtility
+from zope.app.utility.utility import queryNextUtility
+from zope.app.container.contained import Contained
+from zope.app.utility.interfaces import ILocalUtility
+from zope.app.location.interfaces import ILocation
+
+from zope.app.pau import interfaces
+from zope.app.pau.interfaces import IExtractionPlugin
+from zope.app.pau.interfaces import IAuthenticationPlugin
+from zope.app.pau.interfaces import IChallengePlugin
+from zope.app.pau.interfaces import IPrincipalFactoryPlugin
+from zope.app.pau.interfaces import IPrincipalSearchPlugin
+
+
+class IPAU(zope.interface.Interface):
+ """Pluggable Authentication Utility
+ """
+
+ extractors = zope.schema.List(
+ title=u"Credential Extractors",
+ value_type = zope.schema.Choice(vocabulary='ExtractionPlugins'),
+ default=[],
+ )
+
+ authenticators = zope.schema.List(
+ title=u"Authenticators",
+ value_type = zope.schema.Choice(vocabulary='AuthenticationPlugins'),
+ default=[],
+ )
+
+ challengers = zope.schema.List(
+ title=u"Challengers",
+ value_type = zope.schema.Choice(vocabulary='ChallengePlugins'),
+ default=[],
+ )
+
+ factories = zope.schema.List(
+ title=u"Principal Factories",
+ value_type = zope.schema.Choice(vocabulary='PrincipalFactoryPlugins'),
+ default=[],
+ )
+
+ searchers = zope.schema.List(
+ title=u"Search Plugins",
+ value_type = zope.schema.Choice(vocabulary='PrincipalSearchPlugins'),
+ default=[],
+ )
+
+class PAU(object):
+
+ zope.interface.implements(IPAU, IAuthenticationUtility, ISourceQueriables)
+
+ authenticators = extractors = challengers = factories = searchers = ()
+
+ def __init__(self, prefix=''):
+ self.prefix = prefix
+
+ def authenticate(self, request):
+ authenticators = [zapi.queryUtility(IAuthenticationPlugin, name)
+ for name in self.authenticators]
+ for extractor in self.extractors:
+ extractor = zapi.queryUtility(IExtractionPlugin, extractor)
+ if extractor is None:
+ continue
+ credentials = extractor.extractCredentials(request)
+ for authenticator in authenticators:
+ if authenticator is None:
+ continue
+ authenticated = authenticator.authenticateCredentials(
+ credentials)
+ if authenticated is None:
+ continue
+
+ id, info = authenticated
+ return self._create('createAuthenticatedPrincipal',
+ self.prefix+id, info, request)
+ return None
+
+ def _create(self, meth, *args):
+ # We got some data, lets create a user
+ for factory in self.factories:
+ factory = zapi.queryUtility(IPrincipalFactoryPlugin,
+ factory)
+ if factory is None:
+ continue
+
+ principal = getattr(factory, meth)(*args)
+ if principal is None:
+ continue
+
+ return principal
+
+ def getPrincipal(self, id):
+ if not id.startswith(self.prefix):
+ return self._delegate('getPrincipal', id)
+ id = id[len(self.prefix):]
+
+ for searcher in self.searchers:
+ searcher = zapi.queryUtility(IPrincipalSearchPlugin, searcher)
+ if searcher is None:
+ continue
+
+ info = searcher.principalInfo(id)
+ if info is None:
+ continue
+
+ return self._create('createFoundPrincipal', self.prefix+id, info)
+
+ return self._delegate('getPrincipal', self.prefix+id)
+
+ def getQueriables(self):
+ for searcher_id in self.searchers:
+ searcher = zapi.queryUtility(IPrincipalSearchPlugin, searcher_id)
+ yield searcher_id, searcher
+
+
+ def unauthenticatedPrincipal(self):
+ return None
+
+ def unauthorized(self, id, request):
+ protocol = None
+
+ for challenger in self.challengers:
+ challenger = zapi.queryUtility(IChallengePlugin, challenger)
+ if challenger is None:
+ continue # skip non-existant challengers
+
+ challenger_protocol = getattr(challenger, 'protocol', None)
+ if protocol is None or challenger_protocol == protocol:
+ if challenger.challenge(request, request.response):
+ if challenger_protocol is None:
+ return
+ elif protocol is None:
+ protocol = challenger_protocol
+
+ if protocol is None:
+ self._delegate('unauthorized', id, request)
+
+ def _delegate(self, meth, *args):
+ # delegate to next AU
+ next = queryNextUtility(self, IAuthenticationUtility)
+ if next is None:
+ return None
+ return getattr(next, meth)(*args)
+
+
+class LocalPAU(PAU, Persistent, Contained):
+ zope.interface.implements(IPAU, ILocation, ILocalUtility)
Deleted: Zope3/trunk/src/zope/app/pau/principalfolder.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalfolder.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/principalfolder.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,224 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 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.
-#
-##############################################################################
-"""ZODB-based Authentication Source
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-
-import persistent
-
-import zope.interface
-import zope.schema
-
-import zope.app.container.btree
-import zope.app.container.contained
-import zope.app.container.constraints
-import zope.app.container.interfaces
-
-from zope.app.i18n import ZopeMessageIDFactory as _
-
-from zope.app.pas import interfaces
-
-class IInternalPrincipal(zope.interface.Interface):
- """Principal information"""
-
- login = zope.schema.TextLine(
- title=_("Login"),
- description=_("The Login/Username of the principal. "
- "This value can change."),
- required=True)
-
- password = zope.schema.Password(
- title=_(u"Password"),
- description=_("The password for the principal."),
- required=True)
-
- title = zope.schema.TextLine(
- title=_("Title"),
- description=_("Provides a title for the principal."),
- required=True)
-
- description = zope.schema.Text(
- title=_("Description"),
- description=_("Provides a description for the principal."),
- required=False,
- missing_value='',
- default=u'',
- )
-
-
-class IInternalPrincipalContainer(zope.interface.Interface):
- """A container that contains internal principals."""
-
- prefix = zope.schema.TextLine(
- title=_("Prefix"),
- description=_(
- "Prefix to be added to all principal ids to assure "
- "that all ids are unique within the authentication service"
- ),
- required=False,
- missing_value=u"",
- default=u'',
- readonly=True,
- )
-
- zope.app.container.constraints.contains(IInternalPrincipal)
-
-
-class IInternalPrincipalContained(zope.interface.Interface):
- """Principal information"""
-
- zope.app.container.constraints.containers(IInternalPrincipalContainer)
-
-
-class ISearchSchema(zope.interface.Interface):
- """Search Interface for this Principal Provider"""
-
- search = zope.schema.TextLine(
- title=_("Search String"),
- description=_("A Search String"),
- required=False,
- default=u'',
- missing_value=u'',
- )
-
-class PrincipalInformation(
- persistent.Persistent,
- zope.app.container.contained.Contained,
- ):
- """An internal principal for Persistent Principal Folder.
- """
- zope.interface.implements(IInternalPrincipal, IInternalPrincipalContained)
-
- def __init__(self, login, password, title, description=u''):
- self._login = login
- self.password = password
- self.title = title
- self.description = description
-
- def getLogin(self):
- return self._login
-
- def setLogin(self, login):
- oldLogin = self._login
- self._login = login
- if self.__parent__ is not None:
- try:
- self.__parent__.notifyLoginChanged(oldLogin, self)
- except ValueError:
- self._login = oldLogin
- raise
-
- login = property(getLogin, setLogin)
-
- def __getitem__(self, attr):
- if attr in ('title', 'description'):
- return getattr(self, attr)
-
-class PrincipalFolder(zope.app.container.btree.BTreeContainer):
- """A Persistent Principal Folder and Authentication plugin
- """
- zope.interface.implements(interfaces.ISearchableAuthenticationPlugin,
- interfaces.IQuerySchemaSearch,
- IInternalPrincipalContainer)
-
- def __init__(self, prefix=''):
- self.prefix = unicode(prefix)
- super(PrincipalFolder, self).__init__()
- self.__id_by_login = self._newContainerData()
-
- def notifyLoginChanged(self, oldLogin, principal):
- """Notify the Container about changed login of a principal.
-
- We need this, so that our second tree can be kept up-to-date.
- """
- # A user with the new login already exists
- if principal.login in self.__id_by_login:
- raise ValueError, 'Principal Login already taken!'
-
- del self.__id_by_login[oldLogin]
- self.__id_by_login[principal.login] = principal.__name__
-
- def __setitem__(self, id, principal):
- """Add principal information
- """
- # A user with the new login already exists
- if principal.login in self.__id_by_login:
- raise ValueError, 'Principal Login already taken!'
-
- super(PrincipalFolder, self).__setitem__(id, principal)
- self.__id_by_login[principal.login] = id
-
- def __delitem__(self, id):
- """Remove principal information
- """
- principal = self[id]
- super(PrincipalFolder, self).__delitem__(id)
- del self.__id_by_login[principal.login]
-
-
- 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
-
- id = self.__id_by_login.get(credentials['login'])
- if id is None:
- return None
-
- principal = self[id]
- if principal.password != credentials['password']:
- return None
-
- id = self.prefix+id
-
- return id, {'login': principal.login, 'title': principal.title,
- 'description': principal.description}
-
- def principalInfo(self, principal_id):
- if principal_id.startswith(self.prefix):
- principal = self.get(principal_id[len(self.prefix):])
- if principal is not None:
- return {
- 'login': principal.login,
- 'title': principal.title,
- 'description': principal.description,
- }
-
-
- schema = ISearchSchema
-
- def search(self, query, start=None, batch_size=None):
- """Search through this principal provider.
- """
- search = query.get('search')
- if search is None:
- return
- i = 0
- n = 1
- for value in self.values():
- if (search in value.title or
- search in value.description or
- search in value.login):
- if not ((start is not None and i < start)
- or
- (batch_size is not None and n > batch_size)):
- n += 1
- yield self.prefix+value.__name__
- i += 1
Copied: Zope3/trunk/src/zope/app/pau/principalfolder.py (from rev 28658, Zope3/trunk/src/zope/app/pas/principalfolder.py)
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalfolder.py 2004-12-20 22:58:33 UTC (rev 28658)
+++ Zope3/trunk/src/zope/app/pau/principalfolder.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -0,0 +1,224 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""ZODB-based Authentication Source
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import persistent
+
+import zope.interface
+import zope.schema
+
+import zope.app.container.btree
+import zope.app.container.contained
+import zope.app.container.constraints
+import zope.app.container.interfaces
+
+from zope.app.i18n import ZopeMessageIDFactory as _
+
+from zope.app.pau import interfaces
+
+class IInternalPrincipal(zope.interface.Interface):
+ """Principal information"""
+
+ login = zope.schema.TextLine(
+ title=_("Login"),
+ description=_("The Login/Username of the principal. "
+ "This value can change."),
+ required=True)
+
+ password = zope.schema.Password(
+ title=_(u"Password"),
+ description=_("The password for the principal."),
+ required=True)
+
+ title = zope.schema.TextLine(
+ title=_("Title"),
+ description=_("Provides a title for the principal."),
+ required=True)
+
+ description = zope.schema.Text(
+ title=_("Description"),
+ description=_("Provides a description for the principal."),
+ required=False,
+ missing_value='',
+ default=u'',
+ )
+
+
+class IInternalPrincipalContainer(zope.interface.Interface):
+ """A container that contains internal principals."""
+
+ prefix = zope.schema.TextLine(
+ title=_("Prefix"),
+ description=_(
+ "Prefix to be added to all principal ids to assure "
+ "that all ids are unique within the authentication service"
+ ),
+ required=False,
+ missing_value=u"",
+ default=u'',
+ readonly=True,
+ )
+
+ zope.app.container.constraints.contains(IInternalPrincipal)
+
+
+class IInternalPrincipalContained(zope.interface.Interface):
+ """Principal information"""
+
+ zope.app.container.constraints.containers(IInternalPrincipalContainer)
+
+
+class ISearchSchema(zope.interface.Interface):
+ """Search Interface for this Principal Provider"""
+
+ search = zope.schema.TextLine(
+ title=_("Search String"),
+ description=_("A Search String"),
+ required=False,
+ default=u'',
+ missing_value=u'',
+ )
+
+class PrincipalInformation(
+ persistent.Persistent,
+ zope.app.container.contained.Contained,
+ ):
+ """An internal principal for Persistent Principal Folder.
+ """
+ zope.interface.implements(IInternalPrincipal, IInternalPrincipalContained)
+
+ def __init__(self, login, password, title, description=u''):
+ self._login = login
+ self.password = password
+ self.title = title
+ self.description = description
+
+ def getLogin(self):
+ return self._login
+
+ def setLogin(self, login):
+ oldLogin = self._login
+ self._login = login
+ if self.__parent__ is not None:
+ try:
+ self.__parent__.notifyLoginChanged(oldLogin, self)
+ except ValueError:
+ self._login = oldLogin
+ raise
+
+ login = property(getLogin, setLogin)
+
+ def __getitem__(self, attr):
+ if attr in ('title', 'description'):
+ return getattr(self, attr)
+
+class PrincipalFolder(zope.app.container.btree.BTreeContainer):
+ """A Persistent Principal Folder and Authentication plugin
+ """
+ zope.interface.implements(interfaces.ISearchableAuthenticationPlugin,
+ interfaces.IQuerySchemaSearch,
+ IInternalPrincipalContainer)
+
+ def __init__(self, prefix=''):
+ self.prefix = unicode(prefix)
+ super(PrincipalFolder, self).__init__()
+ self.__id_by_login = self._newContainerData()
+
+ def notifyLoginChanged(self, oldLogin, principal):
+ """Notify the Container about changed login of a principal.
+
+ We need this, so that our second tree can be kept up-to-date.
+ """
+ # A user with the new login already exists
+ if principal.login in self.__id_by_login:
+ raise ValueError, 'Principal Login already taken!'
+
+ del self.__id_by_login[oldLogin]
+ self.__id_by_login[principal.login] = principal.__name__
+
+ def __setitem__(self, id, principal):
+ """Add principal information
+ """
+ # A user with the new login already exists
+ if principal.login in self.__id_by_login:
+ raise ValueError, 'Principal Login already taken!'
+
+ super(PrincipalFolder, self).__setitem__(id, principal)
+ self.__id_by_login[principal.login] = id
+
+ def __delitem__(self, id):
+ """Remove principal information
+ """
+ principal = self[id]
+ super(PrincipalFolder, self).__delitem__(id)
+ del self.__id_by_login[principal.login]
+
+
+ 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
+
+ id = self.__id_by_login.get(credentials['login'])
+ if id is None:
+ return None
+
+ principal = self[id]
+ if principal.password != credentials['password']:
+ return None
+
+ id = self.prefix+id
+
+ return id, {'login': principal.login, 'title': principal.title,
+ 'description': principal.description}
+
+ def principalInfo(self, principal_id):
+ if principal_id.startswith(self.prefix):
+ principal = self.get(principal_id[len(self.prefix):])
+ if principal is not None:
+ return {
+ 'login': principal.login,
+ 'title': principal.title,
+ 'description': principal.description,
+ }
+
+
+ schema = ISearchSchema
+
+ def search(self, query, start=None, batch_size=None):
+ """Search through this principal provider.
+ """
+ search = query.get('search')
+ if search is None:
+ return
+ i = 0
+ n = 1
+ for value in self.values():
+ if (search in value.title or
+ search in value.description or
+ search in value.login):
+ if not ((start is not None and i < start)
+ or
+ (batch_size is not None and n > batch_size)):
+ n += 1
+ yield self.prefix+value.__name__
+ i += 1
Modified: Zope3/trunk/src/zope/app/pau/principalfolder.txt
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalfolder.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/principalfolder.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -5,13 +5,13 @@
principal information. We create principal information using the
`PrincipalInformation` class:
- >>> import zope.app.pas.principalfolder
- >>> p1 = zope.app.pas.principalfolder.PrincipalInformation(
+ >>> import zope.app.pau.principalfolder
+ >>> p1 = zope.app.pau.principalfolder.PrincipalInformation(
... 'login1', '123', "Principal 1")
- >>> p2 = zope.app.pas.principalfolder.PrincipalInformation(
+ >>> p2 = zope.app.pau.principalfolder.PrincipalInformation(
... 'login2', '456', "The other one")
- >>> principals = zope.app.pas.principalfolder.PrincipalFolder('principal.')
+ >>> principals = zope.app.pau.principalfolder.PrincipalFolder('principal.')
>>> principals['p1'] = p1
>>> principals['p2'] = p2
@@ -71,7 +71,7 @@
>>> for i in range(20):
... i = str(i)
- ... p = zope.app.pas.principalfolder.PrincipalInformation(
+ ... p = zope.app.pau.principalfolder.PrincipalInformation(
... 'l'+i, i, "Dude "+i)
... principals[i] = p
Modified: Zope3/trunk/src/zope/app/pau/principalplugins.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalplugins.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/principalplugins.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -22,7 +22,7 @@
from zope.security.interfaces import IGroupAwarePrincipal
-from zope.app.pas import interfaces
+from zope.app.pau import interfaces
class Principal:
"""A simple Principal
@@ -90,7 +90,7 @@
implements(interfaces.IPrincipalFactoryPlugin)
def createAuthenticatedPrincipal(self, id, info, request):
- """See zope.app.pas.interfaces.IPrincipalFactoryPlugin"""
+ """See zope.app.pau.interfaces.IPrincipalFactoryPlugin"""
principal = Principal(id)
notify(interfaces.AuthenticatedPrincipalCreated(principal,
info, request))
@@ -98,7 +98,7 @@
def createFoundPrincipal(self, id, info):
- """See zope.app.pas.interfaces.IPrincipalFactoryPlugin"""
+ """See zope.app.pau.interfaces.IPrincipalFactoryPlugin"""
principal = Principal(id)
notify(interfaces.FoundPrincipalCreated(principal, info))
return principal
Modified: Zope3/trunk/src/zope/app/pau/principalplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalplugins.zcml 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/principalplugins.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,7 +11,7 @@
/>
<subscriber
- for=".interfaces.IPASPrincipalCreated"
+ for=".interfaces.IPAUPrincipalCreated"
factory=".principalplugins.addTitleAndDescription"
/>
Modified: Zope3/trunk/src/zope/app/pau/sql.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/sql.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/sql.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -13,7 +13,7 @@
##############################################################################
"""SQL Authentication Plugin.
-$Id: sqlauthpas.py,v 1.0 2004/10/11 mriya3
+$Id: sql.py,v 1.0 2004/10/11 mriya3
"""
from zope.app.sqlscript import SQLScript
import zope.interface
Modified: Zope3/trunk/src/zope/app/pau/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/tests.py 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/pau/tests.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -28,7 +28,6 @@
from zope.app.tests import placelesssetup, ztapi
from zope.app.event.tests.placelesssetup import getEvents
from zope.app.tests.setup import placefulSetUp, placefulTearDown
-from zope.app.security.interfaces import IAuthenticationService
from zope.app.session.interfaces import \
IClientId, IClientIdManager, ISession, ISessionDataContainer, \
ISessionPkgData, ISessionData
@@ -59,19 +58,16 @@
def groupSetUp(test):
placelesssetup.setUp()
- services = zapi.getGlobalServices()
- services.defineService(zapi.servicenames.Authentication,
- IAuthenticationService)
def test_suite():
return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.pas.generic'),
- doctest.DocTestSuite('zope.app.pas.httpplugins'),
+ doctest.DocTestSuite('zope.app.pau.generic'),
+ doctest.DocTestSuite('zope.app.pau.httpplugins'),
doctest.DocFileSuite('principalfolder.txt'),
doctest.DocFileSuite('idpicker.txt'),
- doctest.DocTestSuite('zope.app.pas.principalplugins'),
- doctest.DocTestSuite('zope.app.pas.browserplugins',
+ doctest.DocTestSuite('zope.app.pau.principalplugins'),
+ doctest.DocTestSuite('zope.app.pau.browserplugins',
setUp=formAuthSetUp,
tearDown=formAuthTearDown),
doctest.DocFileSuite('README.txt',
Modified: Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -61,7 +61,7 @@
class UnauthenticatedPrincipal(Principal):
implements(IUnauthenticatedPrincipal)
-class AuthService1(object):
+class AuthUtility1(object):
def authenticate(self, request):
return None
@@ -75,7 +75,7 @@
def getPrincipal(self, id):
return UnauthenticatedPrincipal(id)
-class AuthService2(AuthService1):
+class AuthUtility2(AuthUtility1):
def authenticate(self, request):
return Principal('test.bob')
@@ -92,15 +92,24 @@
def raising(self, info, request=None):
self.exceptions.append([info, request])
+
+class UtilityService(object):
+
+ utility = None
+
+ def getUtility(self, interface, name=''):
+ return self.utility
+
+
class ServiceManager(object):
implements(IServiceService) # a dirty lie
- def __init__(self, auth):
- self.auth = auth
+ def __init__(self, utils):
+ self.utils = utils
def getService(self, name):
- if name == Authentication:
- return self.auth
+ if name == 'Utilities':
+ return self.utils
raise ComponentLookupError(name)
class LocatableObject(Location):
@@ -408,9 +417,13 @@
app['f1'] = Folder()
f1 = app['f1']
f1['f2'] = Folder()
- f1.setSiteManager(ServiceManager(AuthService1()))
+ utilservice1 = UtilityService()
+ utilservice1.utility = AuthUtility1()
+ f1.setSiteManager(ServiceManager(utilservice1))
f2 = f1['f2']
- f2.setSiteManager(ServiceManager(AuthService2()))
+ utilservice2 = UtilityService()
+ utilservice2.utility = AuthUtility2()
+ f2.setSiteManager(ServiceManager(utilservice2))
get_transaction().commit()
from zope.app.container.interfaces import ISimpleReadContainer
Modified: Zope3/trunk/src/zope/app/publication/zopepublication.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/zopepublication.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/publication/zopepublication.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -48,6 +48,7 @@
from zope.app.publication.publicationtraverse import PublicationTraverse
from zope.app.security.principalregistry import principalRegistry as prin_reg
from zope.app.security.interfaces import IUnauthenticatedPrincipal
+from zope.app.security.interfaces import IAuthenticationUtility
from zope.app.site.interfaces import ISite
from zope.app.traversing.interfaces import IPhysicallyLocatable
@@ -95,15 +96,16 @@
sm = removeSecurityProxy(ob).getSiteManager()
try:
- auth_service = sm.getService(zapi.servicenames.Authentication)
+ utils = sm.getService(zapi.servicenames.Utilities)
+ auth = utils.getUtility(IAuthenticationUtility)
except ComponentLookupError:
- # No auth service here
+ # No auth utility here
return
# Try to authenticate against the auth service
- principal = auth_service.authenticate(request)
+ principal = auth.authenticate(request)
if principal is None:
- principal = auth_service.unauthenticatedPrincipal()
+ principal = auth.unauthenticatedPrincipal()
if principal is None:
# nothing to do here
return
Modified: Zope3/trunk/src/zope/app/security/browser/auth.py
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/auth.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/auth.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -18,7 +18,7 @@
from zope.interface import implements
from zope.i18n import translate
from zope.app.publisher.interfaces.http import ILogin, ILogout
-from zope.app.security.interfaces import IAuthenticationService
+from zope.app.security.interfaces import IAuthenticationUtility
from zope.app.security.principalregistry import UnauthenticatedPrincipal
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.proxy import removeAllProxies
@@ -27,8 +27,8 @@
search_label = _('search-button', 'Search')
-class AuthServiceSearchView(object):
- __used_for__ = IAuthenticationService
+class AuthUtilitySearchView(object):
+ __used_for__ = IAuthenticationUtility
def __init__(self, context, request):
self.context = context
Deleted: Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -1,62 +0,0 @@
-The Query View for Authentication Services
-==========================================
-
-A regular authentication service will not provide the `ISourceQueriables`
-interface, but it is a queriable itself, since it provides the simple
-`getPrincipals(name)` method:
-
- >>> class Principal:
- ... def __init__(self, id):
- ... self.id = id
-
- >>> class MyAuthService:
- ... data = {'jim': Principal(42), 'don': Principal(0),
- ... 'stephan': Principal(1)}
- ...
- ... def getPrincipals(self, name):
- ... return [principal
- ... for id, principal in self.data.items()
- ... if name in id]
-
-Now that we have our queriable, we create the view for it:
-
- >>> from zope.app.security.browser.auth import AuthServiceSearchView
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
- >>> view = AuthServiceSearchView(MyAuthService(), request)
-
-This allows us to render a search form.
-
- >>> print view.render('test') # doctest: +NORMALIZE_WHITESPACE
- <div class="row">
- <div class="label">
- Search String
- </div>
- <div class="field">
- <input type="text" name="test.searchstring" />
- </div>
- </div>
- <br /><input type="submit" name="test.search" value="Search" />
-
-If we ask for results:
-
- >>> view.results('test')
-
-We don't get any, since we did not provide any. But if we give input:
-
- >>> request.form['test.searchstring'] = 'n'
-
-we still don't get any:
-
- >>> view.results('test')
-
-because we did not press the button. So let's press the button:
-
- >>> request.form['test.search'] = 'Search'
-
-so that we now get results (!):
-
- >>> ids = list(view.results('test'))
- >>> ids.sort()
- >>> ids
- [0, 1]
\ No newline at end of file
Copied: Zope3/trunk/src/zope/app/security/browser/authutilitysearchview.txt (from rev 28629, Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt)
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/authservicesearchview.txt 2004-12-15 23:52:41 UTC (rev 28629)
+++ Zope3/trunk/src/zope/app/security/browser/authutilitysearchview.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -0,0 +1,62 @@
+The Query View for Authentication Utilities
+===========================================
+
+A regular authentication service will not provide the `ISourceQueriables`
+interface, but it is a queriable itself, since it provides the simple
+`getPrincipals(name)` method:
+
+ >>> class Principal:
+ ... def __init__(self, id):
+ ... self.id = id
+
+ >>> class MyAuthUtility:
+ ... data = {'jim': Principal(42), 'don': Principal(0),
+ ... 'stephan': Principal(1)}
+ ...
+ ... def getPrincipals(self, name):
+ ... return [principal
+ ... for id, principal in self.data.items()
+ ... if name in id]
+
+Now that we have our queriable, we create the view for it:
+
+ >>> from zope.app.security.browser.auth import AuthUtilitySearchView
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+ >>> view = AuthUtilitySearchView(MyAuthUtility(), request)
+
+This allows us to render a search form.
+
+ >>> print view.render('test') # doctest: +NORMALIZE_WHITESPACE
+ <div class="row">
+ <div class="label">
+ Search String
+ </div>
+ <div class="field">
+ <input type="text" name="test.searchstring" />
+ </div>
+ </div>
+ <br /><input type="submit" name="test.search" value="Search" />
+
+If we ask for results:
+
+ >>> view.results('test')
+
+We don't get any, since we did not provide any. But if we give input:
+
+ >>> request.form['test.searchstring'] = 'n'
+
+we still don't get any:
+
+ >>> view.results('test')
+
+because we did not press the button. So let's press the button:
+
+ >>> request.form['test.search'] = 'Search'
+
+so that we now get results (!):
+
+ >>> ids = list(view.results('test'))
+ >>> ids.sort()
+ >>> ids
+ [0, 1]
\ No newline at end of file
Modified: Zope3/trunk/src/zope/app/security/browser/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/configure.zcml 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -3,10 +3,10 @@
xmlns:browser="http://namespaces.zope.org/browser">
<adapter
- for="zope.app.security.interfaces.IAuthenticationService
+ for="zope.app.security.interfaces.IAuthenticationUtility
zope.publisher.interfaces.browser.IBrowserRequest"
provides="zope.app.form.browser.interfaces.ISourceQueryView"
- factory="zope.app.security.browser.auth.AuthServiceSearchView"
+ factory="zope.app.security.browser.auth.AuthUtilitySearchView"
/>
<adapter
Modified: Zope3/trunk/src/zope/app/security/browser/principalterms.py
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/principalterms.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/principalterms.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -42,7 +42,7 @@
if principal_id not in self.context:
raise LookupError, principal_id
- auth = zapi.getService(zapi.servicenames.Authentication)
+ auth = zapi.principals()
principal = auth.getPrincipal(principal_id)
if principal is None:
Modified: Zope3/trunk/src/zope/app/security/browser/principalterms.txt
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/principalterms.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/principalterms.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -3,18 +3,18 @@
Principal Terms are used to support browser interfaces for searching principal
sources. They provide access to tokens and titles for values. The principal
-terms view uses an authentication service to get principal titles. Let's
-create an authentication service to demonstrate how this works:
+terms view uses an authentication utility to get principal titles. Let's
+create an authentication utility to demonstrate how this works:
>>> class Principal:
... def __init__(self, id, title):
... self.id, self.title = id, title
>>> from zope.interface import implements
- >>> from zope.app.security.interfaces import IAuthenticationService
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
>>> from zope.app.security.interfaces import PrincipalLookupError
- >>> class AuthService:
- ... implements(IAuthenticationService)
+ >>> class AuthUtility:
+ ... implements(IAuthenticationUtility)
... data = {'jim': 'Jim Fulton', 'stephan': 'Stephan Richter'}
...
... def getPrincipal(self, id):
@@ -23,18 +23,17 @@
... return Principal(id, title)
... raise PrincipalLookupError
-Now we need to install the authentication service:
+Now we need to install the authentication utility:
>>> from zope.app.tests import ztapi
- >>> ztapi.provideService('Authentication', AuthService(),
- ... IAuthenticationService)
+ >>> ztapi.provideUtility(IAuthenticationUtility, AuthUtility())
We need a principal source so that we can create a view from it.
>>> from zope.app import zapi
>>> class PrincipalSource:
... def __contains__(self, id):
- ... auth = zapi.getService('Authentication')
+ ... auth = zapi.getUtility(IAuthenticationUtility)
... try:
... auth.getPrincipal(id)
... except PrincipalLookupError:
Modified: Zope3/trunk/src/zope/app/security/browser/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/security/browser/tests.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/browser/tests.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -22,7 +22,7 @@
def test_suite():
return unittest.TestSuite((
- doctest.DocFileSuite('authservicesearchview.txt',
+ doctest.DocFileSuite('authutilitysearchview.txt',
setUp=placelesssetup.setUp,
tearDown=placelesssetup.tearDown),
doctest.DocFileSuite('principalterms.txt',
Modified: Zope3/trunk/src/zope/app/security/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/security/configure.zcml 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/configure.zcml 2004-12-21 03:34:46 UTC (rev 28663)
@@ -22,12 +22,8 @@
<include file="globalmodules.zcml" />
<include file="_protections.zcml" />
- <serviceType
- id="Authentication"
- interface=".interfaces.IAuthenticationService" />
-
- <service
- serviceType="Authentication"
+ <utility
+ provides=".interfaces.IAuthenticationUtility"
component=".principalregistry.principalRegistry" />
<localUtility class=".permission.LocalPermission">
Modified: Zope3/trunk/src/zope/app/security/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/security/interfaces.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/interfaces.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -33,23 +33,22 @@
Authenticated principals are preferable to UnauthenticatedPrincipals.
"""
-class IAuthenticationService(Interface):
+class IAuthenticationUtility(Interface):
"""Provide support for establishing principals for requests.
- This is implemented by performing protocol-specific actions,
- such as issuing challenges or providing login interfaces.
+ This is implemented by performing protocol-specific actions, such as
+ issuing challenges or providing login interfaces.
- IAuthenticationService objects are used to implement
- authentication services. Because they implement services, they are
- expected to collaborate with services in other contexts. Client
- code doesn't search a context and call multiple services. Instead,
- client code will call the most specific service in a place and
- rely on the service to delegate to other services as necessary.
+ `IAuthenticationUtility` objects are used to implement authentication
+ utilities. Because they implement services, they are expected to
+ collaborate with services in other contexts. Client code doesn't search a
+ context and call multiple services. Instead, client code will call the
+ most specific service in a place and rely on the service to delegate to
+ other services as necessary.
- The interface doesn't include methods for data
- management. Services may use external data and not allow
- management in Zope. Simularly, the data to be managed may vary
- with different implementations of a service.
+ The interface doesn't include methods for data management. Services may
+ use external data and not allow management in Zope. Simularly, the data to
+ be managed may vary with different implementations of a service.
"""
def authenticate(request):
@@ -127,10 +126,15 @@
similar to (e.g. contain) the given name.
"""
+############################################################################
+# BBB: 12/15/2004
+IAuthenticationService = IAuthenticationUtility
+############################################################################
+
class ILoginPassword(Interface):
"""A password based login.
- An IAuthenticationService would use this (adapting a request),
+ An `IAuthenticationUtility` would use this (adapting a request),
to discover the login/password passed from the user, or to
indicate that a login is required.
"""
Modified: Zope3/trunk/src/zope/app/security/principal.py
===================================================================
--- Zope3/trunk/src/zope/app/security/principal.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/principal.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -15,9 +15,9 @@
$Id$
"""
+from zope.app import zapi
from zope.app.security.interfaces import PrincipalLookupError
-from zope.app import zapi
-from zope.app.servicenames import Authentication
+from zope.app.security.interfaces import IAuthenticationUtility
# BBB Backward Compatibility
from zope.exceptions import NotFoundError
@@ -25,7 +25,7 @@
def checkPrincipal(context, principal_id):
- auth = zapi.getService(Authentication, context)
+ auth = zapi.getUtility(IAuthenticationUtility, context=context)
try:
if auth.getPrincipal(principal_id):
return
Modified: Zope3/trunk/src/zope/app/security/principalregistry.py
===================================================================
--- Zope3/trunk/src/zope/app/security/principalregistry.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/principalregistry.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,7 +11,7 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Global Authentication Service or Principal Registry
+"""Global Authentication Utility or Principal Registry
$Id$
"""
@@ -20,7 +20,7 @@
from zope.app.security.interfaces import PrincipalLookupError
from zope.app import zapi
from zope.app.security.interfaces import ILoginPassword
-from zope.app.security.interfaces import IAuthenticationService, IPrincipal
+from zope.app.security.interfaces import IAuthenticationUtility, IPrincipal
from zope.app.security.interfaces import IUnauthenticatedPrincipal
from zope.app.container.contained import Contained, contained
from warnings import warn
@@ -30,9 +30,9 @@
class PrincipalRegistry(object):
- implements(IAuthenticationService)
+ implements(IAuthenticationUtility)
- # Methods implementing IAuthenticationService
+ # Methods implementing IAuthenticationUtility
def authenticate(self, request):
a = ILoginPassword(request, None)
Modified: Zope3/trunk/src/zope/app/security/tests/test_securitydirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/security/tests/test_securitydirectives.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/tests/test_securitydirectives.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -24,7 +24,7 @@
from zope.app.tests.placelesssetup import PlacelessSetup
from zope.app.servicenames import Authentication
-from zope.app.security.interfaces import IAuthenticationService, IPermission
+from zope.app.security.interfaces import IAuthenticationUtility, IPermission
from zope.app.security.principalregistry import principalRegistry
from zope.app.security.settings import Allow
import zope.app.security.tests
@@ -34,12 +34,9 @@
def setUp(self):
super(TestBase, self).setUp()
- services = zapi.getGlobalServices()
+ ztapi.provideUtility(IAuthenticationUtility, principalRegistry)
- services.defineService(Authentication, IAuthenticationService)
- services.provideService(Authentication, principalRegistry)
-
class TestPrincipalDirective(TestBase, unittest.TestCase):
def testRegister(self):
Modified: Zope3/trunk/src/zope/app/security/vocabulary.py
===================================================================
--- Zope3/trunk/src/zope/app/security/vocabulary.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/security/vocabulary.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -22,9 +22,9 @@
from zope.interface import implements
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
from zope.schema.interfaces import ISourceQueriables
-from zope.app.security.interfaces import IPermission
+from zope.app.security.interfaces import IPermission, IAuthenticationUtility
from zope.app.security.interfaces import PrincipalLookupError
-from zope.app.component.localservice import queryNextService
+from zope.app.utility.utility import queryNextUtility
# BBB Backward Compatibility
from zope.exceptions import NotFoundError
@@ -115,25 +115,25 @@
We want to check whether the system knows about a particular
principal, which is referenced via its id. The source will go through
- the most local authentication service to look for the
- principal. Whether the service consults other services to give an
- answer is up to the service itself.
+ the most local authentication utility to look for the
+ principal. Whether the utility consults other utilities to give an
+ answer is up to the utility itself.
First we need to create a dummy service that will return a user, if
the id is 'bob'.
- >>> class DummyService:
+ >>> class DummyUtility:
... def getPrincipal(self, id):
... if id == 'bob':
... return id
... raise PrincipalLookupError(id)
Since we do not want to bring up the entire component architecture, we
- simply monkey patch the `getService()` method to always return our
- dummy authentication service.
+ simply monkey patch the `getUtility()` method to always return our
+ dummy authentication utility.
- >>> temp = zapi.getService
- >>> zapi.getService = lambda name: DummyService()
+ >>> temp = zapi.getUtility
+ >>> zapi.getUtility = lambda iface: DummyUtility()
Now initialize the principal source and test the method
@@ -145,9 +145,9 @@
Now revert our patch.
- >>> zapi.getService = temp
+ >>> zapi.getUtility = temp
"""
- auth = zapi.getService(zapi.servicenames.Authentication)
+ auth = zapi.getUtility(IAuthenticationUtility)
try:
auth.getPrincipal(id)
except PrincipalLookupError:
@@ -157,7 +157,7 @@
"A %s instance raised a NotFoundError in "
"getPrincipals. Raising NotFoundError in this "
"method is deprecated and will no-longer be supported "
- "staring in ZopeX3 3.3. PrincipalLookupError should "
+ "starting in ZopeX3 3.3. PrincipalLookupError should "
"be raised instead."
% auth.__class__.__name__,
DeprecationWarning)
@@ -171,40 +171,42 @@
Queriables are responsible for providing interfaces to search for
principals by a set of given parameters (can be different for the
various queriables). This method will walk up through all of the
- authentication services to look for queriables.
+ authentication utilities to look for queriables.
- >>> class DummyService1:
+ >>> class DummyUtility1:
+ ... implements(IAuthenticationUtility)
... __parent__ = None
... def __repr__(self): return 'dummy1'
- >>> dummy1 = DummyService1()
+ >>> dummy1 = DummyUtility1()
- >>> class DummyService2:
- ... implements(ISourceQueriables)
+ >>> class DummyUtility2:
+ ... implements(ISourceQueriables, IAuthenticationUtility)
... __parent__ = None
... def getQueriables(self):
... return ('1', 1), ('2', 2), ('3', 3)
- >>> dummy2 = DummyService2()
+ >>> dummy2 = DummyUtility2()
- >>> class DummyService3(DummyService2):
+ >>> class DummyUtility3(DummyUtility2):
+ ... implements(IAuthenticationUtility)
... def getQueriables(self):
... return ('4', 4),
- >>> dummy3 = DummyService3()
+ >>> dummy3 = DummyUtility3()
- >>> from zope.app.component.localservice import testingNextService
- >>> testingNextService(dummy1, dummy2, 'Authentication')
- >>> testingNextService(dummy2, dummy3, 'Authentication')
+ >>> from zope.app.utility.utility import testingNextUtility
+ >>> testingNextUtility(dummy1, dummy2, IAuthenticationUtility)
+ >>> testingNextUtility(dummy2, dummy3, IAuthenticationUtility)
- >>> temp = zapi.getService
- >>> zapi.getService = lambda name: dummy1
+ >>> temp = zapi.getUtility
+ >>> zapi.getUtility = lambda iface: dummy1
>>> source = PrincipalSource()
>>> list(source.getQueriables())
[(u'0', dummy1), (u'1.1', 1), (u'1.2', 2), (u'1.3', 3), (u'2.4', 4)]
- >>> zapi.getService = temp
+ >>> zapi.getUtility = temp
"""
i = 0
- auth = zapi.getService(zapi.servicenames.Authentication)
+ auth = zapi.getUtility(IAuthenticationUtility)
while True:
queriables = ISourceQueriables(auth, None)
if queriables is None:
@@ -212,7 +214,7 @@
else:
for qid, queriable in queriables.getQueriables():
yield unicode(i)+'.'+unicode(qid), queriable
- auth = queryNextService(auth, zapi.servicenames.Authentication)
+ auth = queryNextUtility(auth, IAuthenticationUtility)
if auth is None:
break
i += 1
Modified: Zope3/trunk/src/zope/app/securitypolicy/browser/granting.txt
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/browser/granting.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/browser/granting.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -25,16 +25,16 @@
>>> ztapi.provideUtility(IPermission, Permission(u'permission3',
... u'Permission 3'), u'permission3')
- - Authentication Service
+ - Authentication Utility
>>> class Principal:
... def __init__(self, id, title): self.id, self.title = id, title
- >>> from zope.app.security.interfaces import IAuthenticationService
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
>>> from zope.app.security.interfaces import PrincipalLookupError
>>> from zope.interface import implements
- >>> class AuthService:
- ... implements(IAuthenticationService)
+ >>> class AuthUtility:
+ ... implements(IAuthenticationUtility)
... data = {'jim': Principal('jim', 'Jim Fulton'),
... 'stephan': Principal('stephan', 'Stephan Richter')}
...
@@ -49,8 +49,7 @@
... for principal in self.data.values()
... if search in principal.title]
- >>> ztapi.provideService('Authentication', AuthService(),
- ... IAuthenticationService)
+ >>> ztapi.provideUtility(IAuthenticationUtility, AuthUtility())
- Security-related Adapters
@@ -91,10 +90,10 @@
>>> from zope.app.form.browser.interfaces import ITerms
>>> ztapi.browserViewProviding(IPrincipalSource, PrincipalTerms, ITerms)
- >>> from zope.app.security.browser.auth import AuthServiceSearchView
+ >>> from zope.app.security.browser.auth import AuthUtilitySearchView
>>> from zope.app.form.browser.interfaces import ISourceQueryView
- >>> ztapi.browserViewProviding(IAuthenticationService,
- ... AuthServiceSearchView,
+ >>> ztapi.browserViewProviding(IAuthenticationUtility,
+ ... AuthUtilitySearchView,
... ISourceQueryView)
Modified: Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalpermissionmanager.py
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalpermissionmanager.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalpermissionmanager.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -21,7 +21,8 @@
from zope.app.tests import ztapi
from zope.app.tests.placelesssetup import PlacelessSetup
-from zope.app.security.interfaces import IAuthenticationService, IPermission
+from zope.app.security.interfaces import IPermission
+from zope.app.security.interfaces import IAuthenticationUtility
from zope.app.security.permission import Permission
from zope.app.servicenames import Authentication
@@ -41,12 +42,9 @@
def setUp(self):
super(Test, self).setUp()
- services = zapi.getGlobalServices()
+ ztapi.provideUtility(IAuthenticationUtility, principalRegistry)
- services.defineService(Authentication, IAuthenticationService)
- services.provideService(Authentication, principalRegistry)
-
def _make_principal(self, id=None, title=None):
p = principalRegistry.definePrincipal(
id or 'APrincipal',
Modified: Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalrolemanager.py
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalrolemanager.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/tests/test_principalrolemanager.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -20,9 +20,8 @@
from zope.app import zapi
from zope.app.tests import ztapi
from zope.app.tests.placelesssetup import PlacelessSetup
-from zope.app.servicenames import Authentication
-from zope.app.security.interfaces import IAuthenticationService
+from zope.app.security.interfaces import IAuthenticationUtility
from zope.app.security.settings import Allow, Deny
from zope.app.security.principalregistry import principalRegistry
@@ -39,11 +38,8 @@
def setUp(self):
super(Test, self).setUp()
- services = zapi.getGlobalServices()
+ ztapi.provideUtility(IAuthenticationUtility, principalRegistry)
- services.defineService(Authentication, IAuthenticationService)
- services.provideService(Authentication, principalRegistry)
-
def _make_principal(self, id=None, title=None):
p = principalRegistry.definePrincipal(
id or 'APrincipal',
Modified: Zope3/trunk/src/zope/app/securitypolicy/tests/test_securitydirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/tests/test_securitydirectives.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/tests/test_securitydirectives.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -17,16 +17,16 @@
"""
import unittest
+from zope.configuration import xmlconfig
+from zope.configuration.config import ConfigurationConflictError
+
from zope.app import zapi
from zope.app.tests import ztapi
-from zope.app.servicenames import Authentication
-from zope.app.security.interfaces import IAuthenticationService
-from zope.configuration.config import ConfigurationConflictError
-from zope.configuration import xmlconfig
from zope.app.tests.placelesssetup import PlacelessSetup
from zope.app.security.interfaces import IPermission
+from zope.app.security.interfaces import IAuthenticationUtility
from zope.app.security.permission import Permission
from zope.app.security.settings import Allow
from zope.app.security.principalregistry import principalRegistry
@@ -52,12 +52,9 @@
def setUp(self):
super(TestBase, self).setUp()
- services = zapi.getGlobalServices()
+ ztapi.provideUtility(IAuthenticationUtility, principalRegistry)
- services.defineService(Authentication, IAuthenticationService)
- services.provideService(Authentication, principalRegistry)
-
class TestRoleDirective(TestBase, unittest.TestCase):
def testRegister(self):
Modified: Zope3/trunk/src/zope/app/securitypolicy/tests/test_zopepolicy.py
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/tests/test_zopepolicy.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/tests/test_zopepolicy.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -24,7 +24,6 @@
from zope.app.annotation.interfaces import IAttributeAnnotatable
from zope.app.annotation.interfaces import IAnnotations
from zope.app.annotation.attribute import AttributeAnnotations
-from zope.app.security.interfaces import IAuthenticationService
from zope.app.securitypolicy.interfaces import IGrantInfo
from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager
@@ -57,8 +56,6 @@
ztapi.provideAdapter(
IAnnotatable, IGrantInfo,
AnnotationGrantInfo)
- zapi.getGlobalServices().defineService('Authentication',
- IAuthenticationService)
def test_suite():
Modified: Zope3/trunk/src/zope/app/securitypolicy/zopepolicy.txt
===================================================================
--- Zope3/trunk/src/zope/app/securitypolicy/zopepolicy.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/securitypolicy/zopepolicy.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -496,16 +496,17 @@
For our examples here, we'll create and register a stub principal
authentication service:
- >>> from zope.app.security.interfaces import IAuthenticationService
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
>>> class FauxPrincipals(dict):
- ... zope.interface.implements(IAuthenticationService)
+ ... zope.interface.implements(IAuthenticationUtility)
... def getPrincipal(self, id):
... return self[id]
>>> auth = FauxPrincipals()
>>> from zope.app.tests import ztapi
- >>> ztapi.provideService('Authentication', auth)
+ >>> ztapi.provideUtility(IAuthenticationUtility, auth)
+ >>> from zope.app import zapi
Let's define a group:
Modified: Zope3/trunk/src/zope/app/workflow/tests/workflowsetup.py
===================================================================
--- Zope3/trunk/src/zope/app/workflow/tests/workflowsetup.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/workflow/tests/workflowsetup.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -15,17 +15,12 @@
$Id$
"""
-from zope.interface import implements
-from zope.component.interfaces import IUtilityService
-
from zope.app import zapi
from zope.app.annotation.interfaces import IAttributeAnnotatable
-from zope.app.security.interfaces import IAuthenticationService
-from zope.app.security.principalregistry import principalRegistry
-from zope.app.servicenames import Authentication, Utilities
+from zope.app.servicenames import Utilities
from zope.app.site.tests.placefulsetup import PlacefulSetup
-from zope.app.utility import LocalUtilityService
from zope.app.tests import setup
+from zope.app.utility import LocalUtilityService
class WorkflowSetup(PlacefulSetup):
@@ -44,9 +39,3 @@
self.default1 = zapi.traverse(self.sm1, "default")
self.cm1 = self.default1.getRegistrationManager()
-
-
- def setupAuthService(self):
- self.root_sm.defineService(Authentication, IAuthenticationService)
- self.root_sm.provideService(Authentication, principalRegistry)
- return zapi.getService(Authentication, self.rootFolder)
Modified: Zope3/trunk/src/zope/app/zapi/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/zapi/README.txt 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/zapi/README.txt 2004-12-21 03:34:46 UTC (rev 28663)
@@ -14,21 +14,23 @@
service is defined, a ComponentLookupError is raised:
>>> from zope.app import zapi
- >>> zapi.principals()
+ >>> zapi.principals() #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- ComponentLookupError: 'Authentication'
+ ComponentLookupError:
+ (<InterfaceClass zope.app.security.interfaces.IAuthenticationUtility>, '')
+
But if we provide an authentication service:
>>> import zope.interface
- >>> from zope.app.security.interfaces import IAuthenticationService
- >>> class FakeAuthenticationService:
- ... zope.interface.implements(IAuthenticationService)
- >>> fake = FakeAuthenticationService()
+ >>> from zope.app.security.interfaces import IAuthenticationUtility
+ >>> class FakeAuthenticationUtility:
+ ... zope.interface.implements(IAuthenticationUtility)
+ >>> fake = FakeAuthenticationUtility()
>>> from zope.app.tests import ztapi
- >>> ztapi.provideService(zapi.servicenames.Authentication, fake)
+ >>> ztapi.provideUtility(IAuthenticationUtility, fake)
Then we should be able to get the service back when we ask for the
principals:
Modified: Zope3/trunk/src/zope/app/zapi/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/zapi/__init__.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/zapi/__init__.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -38,5 +38,6 @@
name = getName
def principals():
- return getServices().getService(servicenames.Authentication)
+ from zope.app.security.interfaces import IAuthenticationUtility
+ return getUtility(IAuthenticationUtility)
Modified: Zope3/trunk/src/zope/app/zapi/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/zapi/tests.py 2004-12-21 03:29:21 UTC (rev 28662)
+++ Zope3/trunk/src/zope/app/zapi/tests.py 2004-12-21 03:34:46 UTC (rev 28663)
@@ -11,21 +11,17 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""XXX short summary goes here.
+"""ZTAPI Tests
$Id$
"""
import unittest
from zope.app.tests import placelesssetup
from zope.app import zapi
-from zope.app.security.interfaces import IAuthenticationService
def setUp(test):
placelesssetup.setUp()
- services = zapi.getGlobalServices()
- services.defineService(zapi.servicenames.Authentication,
- IAuthenticationService)
def test_suite():
from zope.testing import doctest
More information about the Zope3-Checkins
mailing list