From 791ee42164fdc38301ddab9c7efd70321ca083f1 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Fri, 10 Jun 2011 17:20:09 +0200 Subject: [PATCH] appy.gen: added a session invalidation mechanism: authenticated users will be automatically logged out when their Zope session will expire; improvements in the CodeAnalysis system: more Zope-related extensions are recognized: .vpy, .cpy for Python files, .cpt for Zope Page Templates. --- gen/plone25/installer.py | 21 ++++++++++++++++++++- gen/plone25/templates/config.py | 1 + shared/utils.py | 19 +++++++++++-------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/gen/plone25/installer.py b/gen/plone25/installer.py index 7608247..954ba37 100644 --- a/gen/plone25/installer.py +++ b/gen/plone25/installer.py @@ -543,9 +543,24 @@ def traverseWrapper(self, path, response=None, validated_hook=None): if os.path.splitext(path)[-1].lower() not in doNotTrack: # Do nothing when the user gets non-pages userId = self['AUTHENTICATED_USER'].getId() - if userId: loggedUsers[userId] = t + if userId: + loggedUsers[userId] = t + # "Touch" the SESSION object. Else, expiration won't occur. + session = self.SESSION return res +def onDelSession(sessionObject, container): + '''This function is called when a session expires.''' + rq = container.REQUEST + if rq.cookies.has_key('__ac') and rq.cookies.has_key('_ZopeId') and \ + (rq['_ZopeId'] == sessionObject.token): + # The request comes from a guy whose session has expired. + resp = rq.RESPONSE + resp.expireCookie('__ac', path='/') + # If the request is a (secundary) Ajax request, we return an empty page. + resp.write('
For security reasons, your session has ' \ + 'expired.
') + # ------------------------------------------------------------------------------ class ZopeInstaller: '''This Zope installer runs every time Zope starts and encounters this @@ -629,6 +644,10 @@ class ZopeInstaller: cfg.profile_registry.registerProfile(self.productName, self.productName, 'Installation of %s' % self.productName, 'profiles/default', self.productName, cfg.EXTENSION, for_=cfg.IPloneSiteRoot) + # Register a function warning us when a session object is deleted. + app = self.zopeContext._ProductContext__app + if hasattr(app, 'temp_folder'): # This is not the case in test mode + app.temp_folder.session_data.setDelNotificationTarget(onDelSession) def install(self): self.logger.info('is being installed...') diff --git a/gen/plone25/templates/config.py b/gen/plone25/templates/config.py index a1bb398..4cd9dd2 100644 --- a/gen/plone25/templates/config.py +++ b/gen/plone25/templates/config.py @@ -34,6 +34,7 @@ from Products.Archetypes.Extensions.utils import install_subskin from Products.Archetypes.config import TOOL_NAME as ARCHETYPETOOLNAME from Products.Archetypes import listTypes, process_types from Products.GenericSetup import EXTENSION, profile_registry +from Products.Transience.Transience import TransientObjectContainer import appy.gen import logging logger = logging.getLogger('') diff --git a/shared/utils.py b/shared/utils.py index 2726319..30cb92e 100644 --- a/shared/utils.py +++ b/shared/utils.py @@ -197,7 +197,7 @@ def normalizeString(s, usage='fileName'): # ------------------------------------------------------------------------------ typeLetters = {'b': bool, 'i': int, 'j': long, 'f':float, 's':str, 'u':unicode, 'l': list, 'd': dict} - +exts = {'py': ('.py', '.vpy', '.cpy'), 'pt': ('.pt', '.cpt')} # ------------------------------------------------------------------------------ class CodeAnalysis: '''This class holds information about some code analysis (line counts) that @@ -285,10 +285,9 @@ class CodeAnalysis: '''Analyses file named p_fileName.''' self.numberOfFiles += 1 theFile = file(fileName) - if fileName.endswith('.py'): - self.analysePythonFile(theFile) - elif fileName.endswith('.pt'): - self.analyseZptFile(theFile) + ext = os.path.splitext(fileName)[1] + if ext in exts['py']: self.analysePythonFile(theFile) + elif ext in exts['pt']: self.analyseZptFile(theFile) theFile.close() def printReport(self): @@ -330,6 +329,8 @@ class LinesCounter: # or real code within a given part of self.folder code hierarchy. testMarker1 = '%stest%s' % (os.sep, os.sep) testMarker2 = '%stest' % os.sep + testMarker3 = '%stests%s' % (os.sep, os.sep) + testMarker4 = '%stests' % os.sep j = os.path.join for root, folders, files in os.walk(self.folder): rootName = os.path.basename(root) @@ -338,13 +339,15 @@ class LinesCounter: continue # Are we in real code or in test code ? self.inTest = False - if root.endswith(testMarker2) or (root.find(testMarker1) != -1): + if root.endswith(testMarker2) or (root.find(testMarker1) != -1) or \ + root.endswith(testMarker4) or (root.find(testMarker3) != -1): self.inTest = True # Scan the files in this folder for fileName in files: - if fileName.endswith('.py'): + ext = os.path.splitext(fileName)[1] + if ext in exts['py']: self.python[self.inTest].analyseFile(j(root, fileName)) - elif fileName.endswith('.pt'): + elif ext in exts['pt']: self.zpt[self.inTest].analyseFile(j(root, fileName)) self.printReport() # ------------------------------------------------------------------------------