Added the possibility to list logged users.

This commit is contained in:
Gaetan Delannay 2010-01-17 22:01:14 +01:00
parent 16a0a90bbf
commit 08c5abdd49
3 changed files with 61 additions and 1 deletions

View file

@ -2,7 +2,7 @@
Plone product.''' Plone product.'''
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
import os, os.path import os, os.path, time
from StringIO import StringIO from StringIO import StringIO
from sets import Set from sets import Set
import appy import appy
@ -397,6 +397,12 @@ class PloneInstaller:
# Call custom installer if any # Call custom installer if any
if hasattr(self.appyTool, 'install'): if hasattr(self.appyTool, 'install'):
self.tool.executeAppyAction('install', reindex=False) self.tool.executeAppyAction('install', reindex=False)
# Patch the "logout" action with a custom Appy one that updates the
# list of currently logged users.
for action in site.portal_membership._actions:
if action.id == 'logout':
action.setActionExpression(
'string:${portal_url}/%s/logout' % self.toolInstanceName)
# Replace Plone front-page with an application-specific page if needed # Replace Plone front-page with an application-specific page if needed
if self.appFrontPage: if self.appFrontPage:
frontPageName = self.productName + 'FrontPage' frontPageName = self.productName + 'FrontPage'
@ -447,6 +453,22 @@ class PloneInstaller:
self.log("Uninstallation of %s done." % self.productName) self.log("Uninstallation of %s done." % self.productName)
return self.toLog.getvalue() return self.toLog.getvalue()
# Stuff for tracking user activity ---------------------------------------------
loggedUsers = {}
originalTraverse = None
doNotTrack = ('.jpg','.gif','.png','.js','.class','.css')
def traverseWrapper(self, path, response=None, validated_hook=None):
'''This function is called every time a users gets a URL, this is used for
tracking user activity. self is a BaseRequest'''
res = originalTraverse(self, path, response, validated_hook)
t = time.time()
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
return res
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
class ZopeInstaller: class ZopeInstaller:
'''This Zope installer runs every time Zope starts and encounters this '''This Zope installer runs every time Zope starts and encounters this
@ -494,6 +516,17 @@ class ZopeInstaller:
constructors = (constructors[i],), constructors = (constructors[i],),
permission = self.addContentPermissions[className]) permission = self.addContentPermissions[className])
def enableUserTracking(self):
'''Enables the machinery allowing to know who is currently logged in.
Information about logged users will be stored in RAM, in the variable
named loggedUsers defined above.'''
global originalTraverse
if not originalTraverse:
# User tracking is not enabled yet. Do it now.
BaseRequest = self.ploneStuff['BaseRequest']
originalTraverse = BaseRequest.traverse
BaseRequest.traverse = traverseWrapper
def finalizeInstallation(self): def finalizeInstallation(self):
'''Performs some final installation steps.''' '''Performs some final installation steps.'''
# Apply customization policy if any # Apply customization policy if any
@ -505,5 +538,6 @@ class ZopeInstaller:
self.installApplication() self.installApplication()
self.installTool() self.installTool()
self.installTypes() self.installTypes()
self.enableUserTracking()
self.finalizeInstallation() self.finalizeInstallation()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -724,4 +724,29 @@ class ToolMixin(AbstractMixin):
text = self.translate('%s_list_%s' % (appyType['label'], v)) text = self.translate('%s_list_%s' % (appyType['label'], v))
res.append((v, self.truncate(text, 30))) res.append((v, self.truncate(text, 30)))
return res return res
def logout(self):
'''Logs out the current user when he clicks on "disconnect".'''
rq = self.REQUEST
userId = self.portal_membership.getAuthenticatedMember().getId()
# Perform the logout in acl_users
try:
self.acl_users.logout(rq)
except:
pass
skinvar = self.portal_skins.getRequestVarname()
path = '/' + self.absolute_url(1)
if rq.has_key(skinvar) and not self.portal_skins.getCookiePersistence():
rq.RESPONSE.expireCookie(skinvar, path=path)
# Invalidate existing sessions, but only if they exist.
sdm = self.session_data_manager
session = sdm.getSessionData(create=0)
if session is not None:
session.invalidate()
from Products.CMFPlone import transaction_note
transaction_note('Logged out')
# Remove user from variable "loggedUsers"
from appy.gen.plone25.installer import loggedUsers
if loggedUsers.has_key(userId): del loggedUsers[userId]
return self.goto(self.getParentNode().absolute_url())
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -26,6 +26,7 @@ def countTest():
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
from config import * from config import *
from ZPublisher.HTTPRequest import BaseRequest
import logging import logging
try: try:
import CustomizationPolicy import CustomizationPolicy