[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/pas/ Added quiet a
bit of plugins that almost make PAS work. We just need a
Stephan Richter
srichter at cosmos.phy.tufts.edu
Mon Oct 11 03:18:18 EDT 2004
Log message for revision 27940:
Added quiet a bit of plugins that almost make PAS work. We just need a
screen to add principals to a persistent storage now.
Also refactored the ZCML quiet a bit and did some renaming.
Changed:
A Zope3/trunk/src/zope/app/pas/authenticationplugins.zcml
A Zope3/trunk/src/zope/app/pas/challengeplugins.zcml
U Zope3/trunk/src/zope/app/pas/configure.zcml
A Zope3/trunk/src/zope/app/pas/extractionplugins.zcml
D Zope3/trunk/src/zope/app/pas/httpplugin.py
A Zope3/trunk/src/zope/app/pas/httpplugins.py
A Zope3/trunk/src/zope/app/pas/principalplugins.py
A Zope3/trunk/src/zope/app/pas/principalplugins.zcml
U Zope3/trunk/src/zope/app/pas/tests.py
A Zope3/trunk/src/zope/app/pas/zodb.py
-=-
Added: Zope3/trunk/src/zope/app/pas/authenticationplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/authenticationplugins.zcml 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/authenticationplugins.zcml 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,37 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+
+ <localUtility class=".zodb.PersistentPrincipalStorage">
+
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
+
+ <require
+ permission="zope.ManageContent"
+ interface="zope.app.container.interfaces.IContainer" />
+
+ <require
+ permission="zope.ManageContent"
+ interface=".interfaces.IAuthenticationPlugin" />
+
+ </localUtility>
+
+
+ <browser:addMenuItem
+ title="PAS Authentication Plugin"
+ description="A PAS Authentication Plugin"
+ class="zope.app.pas.zodb.PersistentPrincipalStorage"
+ permission="zope.ManageContent"
+ />
+
+ <browser:tool
+ interface=".interfaces.IAuthenticationPlugin"
+ title="PAS Authentication Plugin"
+ description="PAS Authentication Plugin"
+ />
+
+
+</configure>
Added: Zope3/trunk/src/zope/app/pas/challengeplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/challengeplugins.zcml 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/challengeplugins.zcml 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,30 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope">
+
+ <localUtility class=".httpplugins.HTTPBasicAuthChallenger">
+
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
+
+ <require
+ permission="zope.ManageContent"
+ interface=".interfaces.IChallengePlugin" />
+
+ </localUtility>
+
+ <browser:tool
+ interface=".interfaces.IChallengePlugin"
+ title="PAS Challenge Plugin"
+ description="PAS Challenge Plugin"
+ />
+
+ <browser:addMenuItem
+ title="PAS Challenge Plugin"
+ description="A PAS Challenge Plugin"
+ class="zope.app.pas.httpplugins.HTTPBasicAuthChallenger"
+ permission="zope.ManageContent"
+ />
+
+</configure>
Modified: Zope3/trunk/src/zope/app/pas/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/configure.zcml 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/configure.zcml 2004-10-11 07:18:18 UTC (rev 27940)
@@ -30,12 +30,6 @@
menu="zmi_views" title="Edit"
permission="zope.ManageServices" />
- <interface interface="zope.app.pas.interfaces.IExtractionPlugin" />
- <interface interface="zope.app.pas.interfaces.IAuthenticationPlugin" />
- <interface interface="zope.app.pas.interfaces.IChallengePlugin" />
- <interface interface="zope.app.pas.interfaces.IPrincipalFactoryPlugin" />
- <interface interface="zope.app.pas.interfaces.IPrincipalSearchPlugin" />
-
<vocabulary
name="ExtractionPlugins"
factory="zope.app.utility.vocabulary.UtilityVocabulary"
@@ -71,52 +65,9 @@
nameOnly="True"
/>
- <localUtility class=".httpplugin.HTTPBasicAuthExtractor">
-
- <implements
- interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
-
- <require
- permission="zope.ManageContent"
- interface=".interfaces.IExtractionPlugin" />
-
- </localUtility>
-
- <localUtility class=".httpplugin.HTTPBasicAuthChallenger">
-
- <implements
- interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
-
- <require
- permission="zope.ManageContent"
- interface=".interfaces.IExtractionPlugin" />
-
- </localUtility>
-
- <browser:tool
- interface=".interfaces.IExtractionPlugin"
- title="PAS Extraction Plugin"
- description="PAS Extraction Plugin"
- />
+ <include file="extractionplugins.zcml" />
+ <include file="challengeplugins.zcml" />
+ <include file="principalplugins.zcml" />
+ <include file="authenticationplugins.zcml" />
- <browser:tool
- interface=".interfaces.IChallengePlugin"
- title="PAS Challenge Plugin"
- description="PAS Challenge Plugin"
- />
-
- <browser:addMenuItem
- title="PAS Extraction Plugin"
- description="A PAS Extraction Plugin"
- class="zope.app.pas.httpplugin.HTTPBasicAuthExtractor"
- permission="zope.ManageContent"
- />
-
- <browser:addMenuItem
- title="PAS Challenge Plugin"
- description="A PAS Challenge Plugin"
- class="zope.app.pas.httpplugin.HTTPBasicAuthChallenger"
- permission="zope.ManageContent"
- />
-
</configure>
Added: Zope3/trunk/src/zope/app/pas/extractionplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/extractionplugins.zcml 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/extractionplugins.zcml 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,30 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope">
+
+ <localUtility class=".httpplugins.HTTPBasicAuthExtractor">
+
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
+
+ <require
+ permission="zope.ManageContent"
+ interface=".interfaces.IExtractionPlugin" />
+
+ </localUtility>
+
+ <browser:tool
+ interface=".interfaces.IExtractionPlugin"
+ title="PAS Extraction Plugin"
+ description="PAS Extraction Plugin"
+ />
+
+ <browser:addMenuItem
+ title="PAS Extraction Plugin"
+ description="A PAS Extraction Plugin"
+ class="zope.app.pas.httpplugins.HTTPBasicAuthExtractor"
+ permission="zope.ManageContent"
+ />
+
+</configure>
Deleted: Zope3/trunk/src/zope/app/pas/httpplugin.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/httpplugin.py 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/httpplugin.py 2004-10-11 07:18:18 UTC (rev 27940)
@@ -1,76 +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.
-#
-##############################################################################
-"""PAS plugins related to HTTP
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import base64
-from persistent import Persistent
-from zope.interface import implements
-
-from zope.app.container.contained import Contained
-from interfaces import IExtractionPlugin, IChallengePlugin
-
-
-class HTTPBasicAuthExtractor(Persistent, Contained):
- """A Basic HTTP Authentication Crendentials Extraction Plugin
-
- First we need to create a request that contains some credentials.
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest(
- ... environ={'HTTP_AUTHORIZATION': u'Basic bWdyOm1ncnB3'})
-
- Now create the extraction plugin and get the credentials.
-
- >>> extractor = HTTPBasicAuthExtractor()
- >>> extractor.extractCredentials(request)
- (u'mgr', u'mgrpw')
-
- Make sure we return `None`, if no authentication header has been
- specified.
-
- >>> extractor.extractCredentials(TestRequest()) is None
- True
-
- Also, this extractor can *only* hadle basic authentication.
-
- >>> request = TestRequest({'HTTP_AUTHORIZATION': 'foo bar'})
- >>> extractor.extractCredentials(TestRequest()) is None
- True
- """
- implements(IExtractionPlugin)
-
- def extractCredentials(self, request):
- if request._auth:
- if request._auth.lower().startswith(u'basic '):
- credentials = request._auth.split()[-1]
- username, password = base64.decodestring(credentials).split(':')
- return username.decode('utf-8'), password.decode('utf-8')
-
-
-class HTTPBasicAuthChallenger(Persistent, Contained):
- """A Basic HTTP Authentication Challenge Plugin
-
- """
- implements(IChallengePlugin)
-
- realm = 'Zope 3'
-
- def challenge(self, requests, response):
- response.setHeader("WWW-Authenticate", "basic realm=%s" %self.realm,
- True)
- response.setStatus(401)
- return True
Added: Zope3/trunk/src/zope/app/pas/httpplugins.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/httpplugins.py 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/httpplugins.py 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,99 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""PAS plugins related to HTTP
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import base64
+from persistent import Persistent
+from zope.interface import implements
+from zope.publisher.interfaces.http import IHTTPRequest
+
+from zope.app.container.contained import Contained
+from interfaces import IExtractionPlugin, IChallengePlugin
+
+
+class HTTPBasicAuthExtractor(Persistent, Contained):
+ """A Basic HTTP Authentication Crendentials Extraction Plugin
+
+ First we need to create a request that contains some credentials.
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest(
+ ... environ={'HTTP_AUTHORIZATION': u'Basic bWdyOm1ncnB3'})
+
+ Now create the extraction plugin and get the credentials.
+
+ >>> extractor = HTTPBasicAuthExtractor()
+ >>> extractor.extractCredentials(request)
+ {'login': u'mgr', 'password': u'mgrpw'}
+
+ Make sure we return `None`, if no authentication header has been
+ specified.
+
+ >>> extractor.extractCredentials(TestRequest()) is None
+ True
+
+ Also, this extractor can *only* hadle basic authentication.
+
+ >>> request = TestRequest({'HTTP_AUTHORIZATION': 'foo bar'})
+ >>> extractor.extractCredentials(TestRequest()) is None
+ True
+ """
+ implements(IExtractionPlugin)
+
+ def extractCredentials(self, request):
+ if request._auth:
+ if request._auth.lower().startswith(u'basic '):
+ credentials = request._auth.split()[-1]
+ username, password = base64.decodestring(credentials).split(':')
+ return {'login': username.decode('utf-8'),
+ 'password': password.decode('utf-8')}
+
+
+class HTTPBasicAuthChallenger(Persistent, Contained):
+ """A Basic HTTP Authentication Challenge Plugin
+
+ >>> challenger = HTTPBasicAuthChallenger()
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+ >>> response = request.response
+ >>> challenger.challenge(request, response)
+ True
+ >>> response._status
+ 401
+ >>> response.getHeader('WWW-Authenticate', literal=True)
+ 'basic realm=Zope3'
+
+ >>> from zope.publisher.base import TestRequest
+ >>> request = TestRequest('/')
+ >>> response = request.response
+ >>> challenger.challenge(request, response) is None
+ True
+ """
+ implements(IChallengePlugin)
+
+ realm = 'Zope3'
+
+ protocol = 'http auth'
+
+ def challenge(self, request, response):
+ if not IHTTPRequest.providedBy(request):
+ return None
+ response.setHeader("WWW-Authenticate", "basic realm=%s" %self.realm,
+ True)
+ response.setStatus(401)
+ return True
Added: Zope3/trunk/src/zope/app/pas/principalplugins.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalplugins.py 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/principalplugins.py 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,100 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Principal Factory Plugin
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from persistent import Persistent
+
+from zope.event import notify
+from zope.interface import implements
+
+from zope.app.container.contained import Contained
+import interfaces
+
+class Principal:
+ """A simple Principal
+
+ >>> p = Principal(1)
+ >>> p
+ Principal(1)
+ >>> p.id
+ 1
+
+ >>> p = Principal('foo')
+ >>> p
+ Principal('foo')
+ >>> p.id
+ 'foo'
+ """
+
+ def __init__(self, id):
+ self.id = id
+
+ def __repr__(self):
+ return 'Principal(%r)' %self.id
+
+
+class PrincipalFactory(Persistent, Contained):
+ """A simple principal factory.
+
+ First we need to register a simple subscriber that records all events.
+
+ >>> events = []
+ >>> import zope.event
+ >>> zope.event.subscribers.append(events.append)
+
+ Now we create a principal factory and try to create the principals.
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> pf = PrincipalFactory()
+
+ >>> principal = pf.createAuthenticatedPrincipal(1, {}, TestRequest())
+ >>> principal.id
+ 1
+ >>> event = events[0]
+ >>> isinstance(event, interfaces.AuthenticatedPrincipalCreated)
+ True
+ >>> event.principal is principal
+ True
+ >>> event.info
+ {}
+
+ >>> principal = pf.createFoundPrincipal(2, {})
+ >>> principal.id
+ 2
+ >>> event = events[1]
+ >>> isinstance(event, interfaces.FoundPrincipalCreated)
+ True
+ >>> event.principal is principal
+ True
+ >>> event.info
+ {}
+ """
+ implements(interfaces.IPrincipalFactoryPlugin)
+
+ def createAuthenticatedPrincipal(self, id, info, request):
+ """See zope.app.pas.interfaces.IPrincipalFactoryPlugin"""
+ principal = Principal(id)
+ notify(interfaces.AuthenticatedPrincipalCreated(principal,
+ info, request))
+ return principal
+
+
+ def createFoundPrincipal(self, id, info):
+ """See zope.app.pas.interfaces.IPrincipalFactoryPlugin"""
+ principal = Principal(id)
+ notify(interfaces.FoundPrincipalCreated(principal, info))
+ return principal
Added: Zope3/trunk/src/zope/app/pas/principalplugins.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pas/principalplugins.zcml 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/principalplugins.zcml 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,33 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+
+ <localUtility class=".principalplugin.PrincipalFactory">
+
+ <implements
+ interface="zope.app.annotation.interfaces.IAttributeAnnotatable" />
+
+ <require
+ permission="zope.ManageContent"
+ interface=".interfaces.IPrincipalFactoryPlugin" />
+
+ </localUtility>
+
+
+ <browser:addMenuItem
+ title="PAS Principal Factory Plugin"
+ description="A PAS Principal Factory Plugin"
+ class=".principalplugin.PrincipalFactory"
+ permission="zope.ManageContent"
+ />
+
+ <browser:tool
+ interface=".interfaces.IPrincipalFactoryPlugin"
+ title="PAS Principal Factory Plugin"
+ description="PAS Principal Factory Plugin"
+ />
+
+
+</configure>
Modified: Zope3/trunk/src/zope/app/pas/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/tests.py 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/tests.py 2004-10-11 07:18:18 UTC (rev 27940)
@@ -52,16 +52,18 @@
def test_suite():
return unittest.TestSuite((
- doctest.DocTestSuite('zope.app.pas.httpplugin'),
+ doctest.DocTestSuite('zope.app.pas.httpplugins'),
+ doctest.DocTestSuite('zope.app.pas.zodb'),
+ doctest.DocTestSuite('zope.app.pas.principalplugins'),
+ doctest.DocTestSuite('zope.app.pas.browserplugins',
+ setUp=formAuthSetUp,
+ tearDown=formAuthTearDown),
doctest.DocFileSuite('README.txt',
setUp=placelesssetup.setUp,
tearDown=placelesssetup.tearDown,
globs={'provideUtility': ztapi.provideUtility,
'getEvents': getEvents,
}),
- doctest.DocTestSuite('zope.app.pas.browserplugins',
- setUp=formAuthSetUp,
- tearDown=formAuthTearDown),
))
if __name__ == '__main__':
Added: Zope3/trunk/src/zope/app/pas/zodb.py
===================================================================
--- Zope3/trunk/src/zope/app/pas/zodb.py 2004-10-10 20:15:59 UTC (rev 27939)
+++ Zope3/trunk/src/zope/app/pas/zodb.py 2004-10-11 07:18:18 UTC (rev 27940)
@@ -0,0 +1,226 @@
+##############################################################################
+#
+# 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"
+from persistent import Persistent
+from BTrees.IOBTree import IOBTree
+from BTrees.OIBTree import OIBTree
+
+from zope.interface import implements
+
+from zope.app.container.interfaces import IContainer
+from zope.app.container.contained import Contained
+
+import interfaces
+
+
+class PersistentPrincipalStorage(Persistent, Contained):
+ """A Persistent Principal Storage and Authentication plugin
+
+ Whenever the following code refers to `principal`, we mean a tuple of the
+ form (login, password). Since we try not to expose the password, password
+ is always `None` in any output.
+ """
+ implements(interfaces.IAuthenticationPlugin, IContainer)
+
+ def __init__(self):
+ self._principal_by_id = IOBTree()
+ self._id_by_login = OIBTree()
+
+ def __setitem__(self, id, principal):
+ """ See `IContainerNamesContainer`
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps[1] = ('foo', 'bar')
+ >>> pps._principal_by_id[1]
+ ('foo', 'bar')
+ >>> pps._id_by_login['foo']
+ 1
+ """
+ self._principal_by_id[id] = principal
+ self._id_by_login[principal[0]] = id
+
+ def __delitem__(self, id):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps[1] = ('foo', 'bar')
+ >>> del pps[1]
+ >>> pps[1]
+ Traceback (most recent call last):
+ ...
+ KeyError: 1
+ """
+ login = self._principal_by_id[id][0]
+ del self._principal_by_id[id]
+ del self._id_by_login[login]
+
+ def keys(self):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> list(pps.keys())
+ []
+ >>> pps[1] = ('foo', 'bar')
+ >>> list(pps.keys())
+ [1]
+ >>> del pps[1]
+ >>> list(pps.keys())
+ []
+ """
+ return self._principal_by_id.keys()
+
+ def __iter__(self):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> list(pps.keys())
+ []
+ >>> pps[1] = ('foo', 'bar')
+ >>> pps[2] = ('blah', 'baz')
+ >>> ids = [i for i in pps]
+ >>> ids.sort()
+ >>> ids
+ [1, 2]
+ """
+ return iter(self.keys())
+
+ def __getitem__(self, id):
+ """ See `IContainer`
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps[1] = ('foo', 'bar')
+
+ Never expose the password!
+
+ >>> pps[1]
+ ('foo', None)
+ """
+ try:
+ return self._principal_by_id[id][0], None
+ except TypeError:
+ raise KeyError, id
+
+ def get(self, id, default=None):
+ """ See `IContainer`
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> marker = object()
+ >>> pps.get(1, default=marker) is marker
+ True
+ >>> pps[1] = ('foo', 'bar')
+
+ Never expose the password!
+
+ >>> pps.get(1)
+ ('foo', None)
+ """
+ try:
+ return self[id]
+ except KeyError:
+ return default
+
+ def values(self):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps.values()
+ []
+ >>> pps[1] = ('foo', 'bar')
+ >>> pps.values()
+ [('foo', None)]
+ """
+ return [self[id] for id in self]
+
+ def __len__(self):
+ """ See `IContainer`
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> len(pps)
+ 0
+ >>> pps[1] = ('foo', 'bar')
+ >>> len(pps)
+ 1
+ """
+ return len(self._id_by_login)
+
+ def items(self):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps.items()
+ []
+ >>> pps[1] = ('foo', 'bar')
+ >>> pps.items()
+ [(1, ('foo', None))]
+ """
+ return [(id, self[id]) for id in self]
+
+ def __contains__(self, id):
+ """ See `IContainer`.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> 1 in pps
+ False
+ >>> pps[1] = ('foo', 'bar')
+ >>> 1 in pps
+ True
+ """
+ return id in self.keys()
+
+ has_key = __contains__
+
+
+ def authenticateCredentials(self, credentials):
+ """See zope.app.pas.interfaces.IAuthenticationPlugin
+
+ Create an authentication plugin and add a principal to it.
+
+ >>> pps = PersistentPrincipalStorage()
+ >>> pps[1] = ('foo', 'bar')
+
+ >>> pps.authenticateCredentials(1) is None
+ True
+ >>> pps.authenticateCredentials({'blah': 2}) is None
+ True
+ >>> pps.authenticateCredentials({'login': 'foo'}) is None
+ True
+ >>> pps.authenticateCredentials({'password': 'bar'}) is None
+ True
+ >>> pps.authenticateCredentials({'login': 'foo1',
+ ... 'password': 'bar'}) is None
+ True
+ >>> pps.authenticateCredentials({'login': 'foo',
+ ... 'password': 'bar1'}) is None
+ True
+ >>> pps.authenticateCredentials({'login': 'foo', 'password': 'bar'})
+ ('1', {'login': 'foo'})
+ """
+ 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
+
+ if self._principal_by_id[id][1] != credentials['password']:
+ return None
+
+ return str(id), {'login': credentials['login']}
More information about the Zope3-Checkins
mailing list