[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