[Checkins] SVN: lovely.responsecache/trunk/ added a credentials
plugin for user dependant cleint ids.
Juergen Kartnaller
juergen at kartnaller.at
Fri Aug 31 11:03:17 EDT 2007
Log message for revision 79404:
added a credentials plugin for user dependant cleint ids.
Changed:
U lovely.responsecache/trunk/CHANGES.txt
U lovely.responsecache/trunk/setup.py
A lovely.responsecache/trunk/src/lovely/responsecache/credentials.py
A lovely.responsecache/trunk/src/lovely/responsecache/credentials.txt
U lovely.responsecache/trunk/src/lovely/responsecache/tests.py
-=-
Modified: lovely.responsecache/trunk/CHANGES.txt
===================================================================
--- lovely.responsecache/trunk/CHANGES.txt 2007-08-31 12:43:31 UTC (rev 79403)
+++ lovely.responsecache/trunk/CHANGES.txt 2007-08-31 15:03:16 UTC (rev 79404)
@@ -2,6 +2,11 @@
Changes for lovely.responsecache
================================
+2007/07/09 0.2.6a1
+==================
+
+- added a credentials plugin for user dependant cleint ids.
+
2007/07/09 0.2.5
================
Modified: lovely.responsecache/trunk/setup.py
===================================================================
--- lovely.responsecache/trunk/setup.py 2007-08-31 12:43:31 UTC (rev 79403)
+++ lovely.responsecache/trunk/setup.py 2007-08-31 15:03:16 UTC (rev 79404)
@@ -23,7 +23,7 @@
setup(
name = 'lovely.responsecache',
- version = '0.2.5',
+ version = '0.2.6a1',
author = "Lovely Systems",
author_email = "office at lovelysystems.com",
description = "Cache results of ContentProviders",
Added: lovely.responsecache/trunk/src/lovely/responsecache/credentials.py
===================================================================
--- lovely.responsecache/trunk/src/lovely/responsecache/credentials.py (rev 0)
+++ lovely.responsecache/trunk/src/lovely/responsecache/credentials.py 2007-08-31 15:03:16 UTC (rev 79404)
@@ -0,0 +1,75 @@
+##############################################################################
+#
+# Copyright (c) 2006-2007 Lovely Systems 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope import component
+
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.app.session.interfaces import IClientIdManager, ISession
+
+from zope.app.authentication.session import (
+ SessionCredentialsPlugin,
+ SessionCredentials,
+ )
+
+
+class CredentialsPlugIn(SessionCredentialsPlugin):
+ """A credentials plugin which makes sure that the session id is user
+ dependent.
+ """
+
+ def extractCredentials(self, request):
+ if not IHTTPRequest.providedBy(request):
+ return None
+ # first we check if there is a login in the request
+ login = request.get(self.loginfield, None)
+ password = request.get(self.passwordfield, None)
+ credentials = None
+ if login and password:
+ # there is a login in the request, create the credentials from the
+ # request
+ credentials = SessionCredentials(login, password)
+ session = ISession(request, None)
+ sessionData = session.get(
+ 'zope.app.authentication.browserplugins')
+ if credentials is None and not sessionData:
+ return None
+ sessionData = session[
+ 'zope.app.authentication.browserplugins']
+ sessionCredentials = sessionData.get('credentials', None)
+ if credentials:
+ if ( sessionCredentials is None
+ or sessionCredentials.getLogin() != credentials.getLogin()
+ ):
+ # we need a new client id and a new session to make the
+ # session id user specific
+ manager = component.getUtility(IClientIdManager)
+ id = manager.generateUniqueId()
+ manager.setRequestId(request, id)
+ session = ISession(request, None)
+ sessionData = session.get(
+ 'zope.app.authentication.browserplugins')
+ sessionData = session[
+ 'zope.app.authentication.browserplugins']
+ sessionData['credentials'] = credentials
+ else:
+ credentials = sessionData.get('credentials', None)
+ if not credentials:
+ return None
+ return {'login': credentials.getLogin(),
+ 'password': credentials.getPassword()}
+
Property changes on: lovely.responsecache/trunk/src/lovely/responsecache/credentials.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: lovely.responsecache/trunk/src/lovely/responsecache/credentials.txt
===================================================================
--- lovely.responsecache/trunk/src/lovely/responsecache/credentials.txt (rev 0)
+++ lovely.responsecache/trunk/src/lovely/responsecache/credentials.txt 2007-08-31 15:03:16 UTC (rev 79404)
@@ -0,0 +1,88 @@
+==================
+Credentials Plugin
+==================
+
+When using principal dependend cache entries a user specific cache key must be
+created. This is done by using the session id created by the client id
+manager. The default client id manager creates an id based on the browser
+session. If a user is logging in as different users within the same browser
+session the wrong cache entries are used.
+
+The CredentialsPlugIn provided here creates a new session id every time a user
+logges in.
+
+ >>> from lovely.responsecache.credentials import CredentialsPlugIn
+
+ >>> plugin = CredentialsPlugIn()
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+
+ >>> from zope import interface
+ >>> from zope import component
+ >>> from zope.app.session.interfaces import ISession
+ >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+ >>> class FakeSession(dict):
+ ... interface.implements(ISession)
+ ... component.adapts(IDefaultBrowserLayer)
+ ... def __getitem__(self, name):
+ ... if not name in self:
+ ... self[name] = {}
+ ... return dict.__getitem__(self, name)
+
+ >>> session = FakeSession()
+ >>> def getSession(context):
+ ... return session
+ >>> component.provideAdapter(getSession, (IDefaultBrowserLayer,), ISession)
+ >>> session
+ {}
+
+ >>> class FakeClientIdManager(object):
+ ... clientIdCount = 0
+ ... clientId = 0
+ ... def generateUniqueId(self):
+ ... self.clientIdCount += 1
+ ... return self.clientIdCount
+ ... def setRequestId(self, request, id):
+ ... self.clientId = id
+ >>> from zope.app.session.interfaces import IClientIdManager
+ >>> idManager = FakeClientIdManager()
+ >>> component.provideUtility(idManager, IClientIdManager)
+
+We provide no credentials.
+
+ >>> plugin.extractCredentials(request)
+ >>> session
+ {}
+
+Now we provide a login.
+
+ >>> request.form[CredentialsPlugIn.loginfield] = 'jukart'
+ >>> request.form[CredentialsPlugIn.passwordfield] = 'holla'
+
+ >>> plugin.extractCredentials(request)
+ {'login': 'jukart', 'password': 'holla'}
+ >>> idManager.clientId
+ 1
+ >>> plugin.extractCredentials(request)
+ {'login': 'jukart', 'password': 'holla'}
+ >>> idManager.clientId
+ 1
+ >>> session['zope.app.authentication.browserplugins']['credentials'].getLogin()
+ 'jukart'
+
+We login as a different user.
+
+ >>> request.form[CredentialsPlugIn.loginfield] = 'dobee'
+ >>> request.form[CredentialsPlugIn.passwordfield] = 'hoschi'
+ >>> plugin.extractCredentials(request)
+ {'login': 'dobee', 'password': 'hoschi'}
+
+A new client id was requested.
+
+ >>> idManager.clientId
+ 2
+ >>> session['zope.app.authentication.browserplugins']['credentials'].getLogin()
+ 'dobee'
+
Property changes on: lovely.responsecache/trunk/src/lovely/responsecache/credentials.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: lovely.responsecache/trunk/src/lovely/responsecache/tests.py
===================================================================
--- lovely.responsecache/trunk/src/lovely/responsecache/tests.py 2007-08-31 12:43:31 UTC (rev 79403)
+++ lovely.responsecache/trunk/src/lovely/responsecache/tests.py 2007-08-31 15:03:16 UTC (rev 79404)
@@ -39,13 +39,12 @@
def appSetUp(app):
-
configurator.configure(app, {},
names = ['lovely.memcachedclient'])
cache = component.getUtility(IMemcachedClient,
context=app)
cache.invalidateAll()
-
+
layer.defineLayer('ResponseCacheLayer', zcml='ftesting.zcml',
appSetUp=appSetUp,
clean=True)
@@ -58,12 +57,17 @@
def tearDown(test):
setup.placefulTearDown()
+
def test_suite():
level1Suites = (
DocFileSuite(
- 'zcml.txt', setUp=setUp, tearDown=tearDown,
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
+ 'zcml.txt', setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite(
+ 'credentials.txt', setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
)
fsuite = functional.FunctionalDocFileSuite('BROWSER.txt')
fsuite.layer=ResponseCacheLayer
More information about the Checkins
mailing list