[Checkins]
SVN: z3c.authentication/trunk/src/z3c/authentication/cookie/
Last try to implement a life time cookie login
Roger Ineichen
roger at projekt01.ch
Sat Nov 4 20:23:36 EST 2006
Log message for revision 71076:
Last try to implement a life time cookie login
with the option to select between auto login based
on a life time cookie or login for each browser session.
Note:
Don't add the default browser client id manager
and the life time session client id manager in
the same site manager. This will end in mess up
the cookie generation. See the configurator adapter
for a sample setup.
Changed:
U z3c.authentication/trunk/src/z3c/authentication/cookie/BROWSER.txt
U z3c.authentication/trunk/src/z3c/authentication/cookie/README.txt
U z3c.authentication/trunk/src/z3c/authentication/cookie/configurator.py
U z3c.authentication/trunk/src/z3c/authentication/cookie/configure.zcml
U z3c.authentication/trunk/src/z3c/authentication/cookie/interfaces.py
U z3c.authentication/trunk/src/z3c/authentication/cookie/plugin.py
U z3c.authentication/trunk/src/z3c/authentication/cookie/session.py
U z3c.authentication/trunk/src/z3c/authentication/cookie/testing.py
U z3c.authentication/trunk/src/z3c/authentication/cookie/tests.py
-=-
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/BROWSER.txt
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/BROWSER.txt 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/BROWSER.txt 2006-11-05 01:23:34 UTC (rev 71076)
@@ -30,8 +30,8 @@
Let's test the different utilities:
>>> tuple(default.keys())
- (u'CookieClientIdManager', u'CookieCredentialSessionDataContainer',...
- u'PluggableAuthentication')
+ (u'CookieCredentialSessionDataContainer', u'LifeTimeSessionClientIdManager',
+ u'PluggableAuthentication')
Check if the PAU contains a liftime cookie session credential:
@@ -45,10 +45,12 @@
>>> pau.credentialsPlugins
(u'Z3C Cookie Credentials',)
-We also need to check if we got a own CookieClientIdManager which the
-liftime is set to o (zero) whichmeans it never will expire.
+We also need to check if we got a own ICookieClientIdManager which the
+cookieLifetime is set to 0 (zero) which means it never will expire. This
+cookie client id manager is called LifeTimeSessionClientIdManager:
- >>> ccim = default['CookieClientIdManager']
+ >>> rootDefault = traverse(root, '++etc++site/default')
+ >>> ccim = default['LifeTimeSessionClientIdManager']
>>> ccim.cookieLifetime
0
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/README.txt
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/README.txt 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/README.txt 2006-11-05 01:23:34 UTC (rev 71076)
@@ -42,8 +42,8 @@
>>> sm = zope.component.getSiteManager(siteStub)
>>> default = sm['default']
>>> tuple(default.keys())
- (u'CookieClientIdManager', u'CookieCredentialSessionDataContainer',...
- u'PluggableAuthentication')
+ (u'CookieCredentialSessionDataContainer', u'LifeTimeSessionClientIdManager',
+ u'PluggableAuthentication')
Check if the PAU contains a liftime cookie session credential:
@@ -57,10 +57,11 @@
>>> pau.credentialsPlugins
(u'Z3C Cookie Credentials',)
-We also need to check if we got a own CookieClientIdManager which the
-liftime is set to o (zero) whichmeans it never will expire.
+We also need to check if we got a own ICookieClientIdManager which the
+cookieLifetime is set to 0 (zero) which means it never will expire. This
+cookie client id manager is called LifeTimeSessionClientIdManager:
- >>> ccim = default['CookieClientIdManager']
+ >>> ccim = default['LifeTimeSessionClientIdManager']
>>> ccim.cookieLifetime
0
@@ -82,4 +83,6 @@
<z3c.authentication.cookie.session.CookieCredentialSessionDataContainer ...>
>>> ccsdc.timeout
- 0
\ No newline at end of file
+ 0
+
+See also BROWSER.txt for additional tests.
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/configurator.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/configurator.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/configurator.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -80,10 +80,11 @@
sm.registerUtility(ccsdc, ISessionDataContainer,
interfaces.SESSION_KEY)
- # setup cookie client id manager
+ # setup lifetime session cookie client id manager
ccim = CookieClientIdManager()
# Expiry time of 0 means never (well - close enough)
ccim.cookieLifetime = 0
zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(ccim))
- default['CookieClientIdManager'] = ccim
- sm.registerUtility(ccim, IClientIdManager)
+ default['LifeTimeSessionClientIdManager'] = ccim
+ sm.registerUtility(ccim, IClientIdManager,
+ name='LifeTimeSessionClientIdManager')
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/configure.zcml
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/configure.zcml 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/configure.zcml 2006-11-05 01:23:34 UTC (rev 71076)
@@ -2,6 +2,11 @@
xmlns="http://namespaces.zope.org/zope"
i18n_domain="z3c">
+ <class class=".session.LifeTimeSession">
+ <allow interface="zope.app.session.interfaces.ISession" />
+ <implements interface="zope.traversing.interfaces.IPathAdapter" />
+ </class>
+
<class class=".session.CookieCredentialSessionDataContainer">
<require
interface="zope.app.session.interfaces.ISessionDataContainer"
@@ -38,6 +43,17 @@
/>
</class>
+ <adapter
+ factory=".session.LifeTimeClientId"
+ permission="zope.Public"
+ />
+
+ <adapter
+ factory=".session.LifeTimeSession"
+ provides=".interfaces.ILifeTimeSession"
+ permission="zope.Public"
+ />
+
<include package=".browser" />
</configure>
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/interfaces.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/interfaces.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/interfaces.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -19,13 +19,35 @@
import zope.interface
import zope.schema
from zope.app.session.interfaces import ISessionDataContainer
+from zope.app.session.interfaces import ISession
+from zope.app.session.interfaces import IClientId
from zope.app.authentication import interfaces
from zope.app.authentication import session
+
from z3c.i18n import MessageFactory as _
SESSION_KEY = 'z3c.authentication.cookie.ICookieCredentialSessionDataContainer'
+# The BROWSER_SESSION_KEY is a optional session key on which you can register
+# a own ISessionDataContainer, if there is no such named utility, the default
+# unnamed ISessionDataContainer is used. This fallback pattern is provided in
+# ISession._sdc
+BROWSER_SESSION_KEY = 'z3c.authentication.cookie.IBrowserSession-DataContainer'
+
+class ILifeTimeClientId(IClientId):
+ """Life time session client id."""
+
+
+class ILifeTimeSession(ISession):
+ """Session valid over a long time.
+
+ Note this session requires a IClientIdManager configured with a
+ ``cookieLifetime = 0`` registered as a named utility with a
+ ``name = LifeTimeSessionClientIdManager``.
+ """
+
+
class ICookieCredentialSessionDataContainer(ISessionDataContainer):
"""A persistent cookie credential container."""
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/plugin.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/plugin.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/plugin.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -99,9 +99,9 @@
Check if we get the initial login session flag:
- >>> session = ISession(request)
- >>> sessionData = session[interfaces.SESSION_KEY]
- >>> sessionData.get('initialLogin', False)
+ >>> browserSession = ISession(request)
+ >>> browserSessionData = browserSession[interfaces.BROWSER_SESSION_KEY]
+ >>> browserSessionData.get('initialLogin', False)
True
Subsequent requests now have access to the credentials even if they're
@@ -112,14 +112,14 @@
See if the initial login session is still there:
- >>> sessionData.get('initialLogin', False)
+ >>> browserSessionData.get('initialLogin', False)
True
The initial login session didn't get set because we didn't use the
autologin field. Let's try use the autologin field and check the session.
>>> request = TestRequest(login='scott', password='tiger', autologin='on')
- >>> sessionData.get('initialLogin', False)
+ >>> browserSessionData.get('initialLogin', False)
True
We can always provide new credentials explicitly in the request:
@@ -157,7 +157,7 @@
After a logout the initial login session flag must be disabled:
- >>> sessionData.get('initialLogin', False)
+ >>> browserSessionData.get('initialLogin', False)
False
"""
@@ -172,8 +172,13 @@
"""Extracts credentials from a session if they exist."""
if not IHTTPRequest.providedBy(request):
return None
- session = ISession(request, None)
- sessionData = session.get(interfaces.SESSION_KEY)
+
+ lifeTimeSession = interfaces.ILifeTimeSession(request, None)
+ browserSession = ISession(request, None)
+
+ lifeTimeSessionData = lifeTimeSession.get(interfaces.SESSION_KEY)
+ browserSessionData = browserSession.get(interfaces.BROWSER_SESSION_KEY)
+
login = request.get(self.loginfield, None)
password = request.get(self.passwordfield, None)
autologin = request.get(self.autologinfield, None)
@@ -183,34 +188,38 @@
if login and password:
credentials = CookieCredentials(login, password)
# first or relogin login
+
if autologin:
credentials.autologin = True
else:
credentials.autologin = False
initialLogin = True
- elif not sessionData:
+ elif not lifeTimeSessionData:
# go away if no available session and no login try
return None
# not first access on portal
- sessionData = session[interfaces.SESSION_KEY]
+ browserSessionData = browserSession[interfaces.BROWSER_SESSION_KEY]
+ lifeTimeSessionData = lifeTimeSession[interfaces.SESSION_KEY]
+
if credentials:
# first login or relogin
- sessionData['credentials'] = credentials
+ lifeTimeSessionData['credentials'] = credentials
else:
# already logged in or not
- credentials = sessionData.get('credentials', None)
+ credentials = lifeTimeSessionData.get('credentials', None)
+
if not credentials:
# not already logged in
return None
-
if initialLogin:
# set a marker for the initial login in the session
- sessionData['initialLogin'] = True
+ browserSessionData['initialLogin'] = True
# and do login
return self.__doLogin(credentials)
# all below this is a ongoing login or a autologin
- initialLoginSession = sessionData.get('initialLogin', False)
+ initialLoginSession = browserSessionData.get('initialLogin', False)
+
if credentials.autologin == False and not initialLoginSession:
# do not login if autologin is disabled and first login session
# is not set.
@@ -228,8 +237,14 @@
if not IHTTPRequest.providedBy(request):
return False
- sessionData = ISession(request)[interfaces.SESSION_KEY]
- sessionData['credentials'] = None
- sessionData['initialLogin'] = False
+ lifeTimeSession = interfaces.ILifeTimeSession(request, None)
+ browserSession = ISession(request, None)
+
+ lifeTimeSessionData = lifeTimeSession.get(interfaces.SESSION_KEY)
+ browserSessionData = browserSession.get(interfaces.BROWSER_SESSION_KEY)
+
+ # reset the session data
+ lifeTimeSessionData['credentials'] = None
+ browserSessionData['initialLogin'] = False
transaction.commit()
return True
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/session.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/session.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/session.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -16,10 +16,53 @@
"""
import zope.interface
+import zope.component
+from zope.publisher.interfaces import IRequest
+from zope.app.session.interfaces import IClientId
+from zope.app.session.interfaces import IClientIdManager
from zope.app.session.session import PersistentSessionDataContainer
+from zope.app.session.session import Session
from z3c.authentication.cookie import interfaces
+class LifeTimeClientId(str):
+ """Client browser id for LifeTimeSession.
+
+ >>> from z3c.authentication.cookie import testing
+ >>> request = testing.clientIdSetUp()
+
+ >>> id1 = LifeTimeClientId(request)
+ >>> id2 = LifeTimeClientId(request)
+ >>> id1 == id2
+ True
+
+ >>> testing.clientIdTearDown()
+
+ """
+ zope.interface.implements(interfaces.ILifeTimeClientId)
+ zope.component.adapts(IRequest)
+
+ def __new__(cls, request):
+ name = 'LifeTimeSessionClientIdManager'
+ util = zope.component.getUtility(IClientIdManager, name=name)
+ id = util.getClientId(request)
+ return str.__new__(cls, id)
+
+
+class LifeTimeSession(Session):
+ """Session valid over a long time.
+
+ Note this session requires a IClientIdManager configured with a
+ ``cookieLifetime = 0`` registered as a named utility with a
+ ``name = LifeTimeSessionClientIdManager``.
+ """
+ zope.interface.implements(interfaces.ILifeTimeSession)
+ zope.component.adapts(IRequest)
+
+ def __init__(self, request):
+ self.client_id = str(interfaces.ILifeTimeClientId(request))
+
+
class CookieCredentialSessionDataContainer(PersistentSessionDataContainer):
"""A persistent cookie credential container."""
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/testing.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/testing.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/testing.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -16,6 +16,7 @@
"""
__docformat__ = "reStructuredText"
+from cStringIO import StringIO
import unittest
import zope.interface
import zope.schema
@@ -24,13 +25,14 @@
from zope.interface import implements
from zope.component import provideUtility, provideAdapter
from zope.publisher.interfaces import IRequest
+from zope.publisher.http import HTTPRequest
from zope.testing import doctestunit
from zope.app.component import hooks
from zope.app.component.interfaces import ISite
from zope.app.testing import functional
+from zope.app.testing import placelesssetup
from zope.app.testing import setup
-from zope.app.testing import placelesssetup
from zope.app.testing import ztapi
from zope.app.session.interfaces import IClientId
from zope.app.session.interfaces import IClientIdManager
@@ -43,8 +45,7 @@
from z3c.configurator import configurator
from z3c.authentication.cookie import interfaces
-from z3c.authentication.cookie.session import \
- CookieCredentialSessionDataContainer
+from z3c.authentication.cookie import session
###############################################################################
@@ -139,17 +140,41 @@
def sessionSetUp():
- placelesssetup.setUp()
+ # setup client ids
ztapi.provideAdapter(IRequest, IClientId, TestClientId)
+ ztapi.provideAdapter(IRequest, interfaces.ILifeTimeClientId, TestClientId)
+
+ # setup session adapters
ztapi.provideAdapter(IRequest, ISession, Session)
+ ztapi.provideAdapter(IRequest, interfaces.ILifeTimeSession,
+ session.LifeTimeSession)
+
+ # setup client id managers
ztapi.provideUtility(IClientIdManager, CookieClientIdManager())
+ ccim = CookieClientIdManager()
+ ccim.cookieLifetime = 0
+ ztapi.provideUtility(IClientIdManager, ccim,
+ name='LifeTimeSessionClientIdManager')
+
+ # setup session data containers
defaultSDC = PersistentSessionDataContainer()
ztapi.provideUtility(ISessionDataContainer, defaultSDC, '')
- cookieSDC = CookieCredentialSessionDataContainer()
+ cookieSDC = session.CookieCredentialSessionDataContainer()
ztapi.provideUtility(ISessionDataContainer, cookieSDC,
interfaces.SESSION_KEY)
+def clientIdSetUp():
+ placelesssetup.setUp()
+ sessionSetUp()
+ request = HTTPRequest(StringIO(), {}, None)
+ return request
+
+
+def clientIdTearDown():
+ placelesssetup.tearDown()
+
+
def FunctionalDocFileSuite(path, **kw):
"""Including relative path setup."""
globs = {'getRootFolder': getRootFolder}
Modified: z3c.authentication/trunk/src/z3c/authentication/cookie/tests.py
===================================================================
--- z3c.authentication/trunk/src/z3c/authentication/cookie/tests.py 2006-11-05 01:16:14 UTC (rev 71075)
+++ z3c.authentication/trunk/src/z3c/authentication/cookie/tests.py 2006-11-05 01:23:34 UTC (rev 71076)
@@ -26,6 +26,8 @@
def test_suite():
return unittest.TestSuite((
+ doctest.DocTestSuite('z3c.authentication.cookie.session',
+ setUp=testing.siteSetUp, tearDown=testing.siteTearDown),
doctest.DocTestSuite('z3c.authentication.cookie.plugin',
setUp=testing.siteSetUp, tearDown=testing.siteTearDown),
doctestunit.DocFileSuite('README.txt',
More information about the Checkins
mailing list