This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
expression/src/core/sessions.py

269 lines
9.3 KiB
Python

# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Sessions Module"""
import errno
import os
import socket
import libxml2
import dataholders
import directories
import elements
import environs
import faults
import filesystems
import locations
import logs
import modules
import namespaces
import stations
import things
class Session(things.Thing):
_account = None
def deleteAccountPath(self):
nodes = self.evaluateXpath("yep:account")
if nodes:
node = nodes[0]
node.unlinkNode()
node.freeNode()
self.getDataHolder().isDirty = True
def deletePublishToken(self):
nodes = self.evaluateXpath("yep:publishToken")
if nodes:
node = nodes[0]
node.unlinkNode()
node.freeNode()
self.getDataHolder().isDirty = True
def getAccount(self):
if self._account is None:
accountAbsolutePath = self.getAccountAbsolutePath()
if accountAbsolutePath:
try:
accountHolder = dataholders.DataHolder(
pathFragment = accountAbsolutePath, mimeType = "text/xml",
isRootElder = True,
containedFileSystem = filesystems.PartialFileSystem(accountAbsolutePath))
except IOError, error:
if error.errno == errno.ENOENT:
logs.debug("""Account at path "%s" doesn't exist.""" % accountAbsolutePath)
self._account = "none"
else:
raise
else:
self._account = accountHolder.getRootElement()
else:
accountNodes = self.evaluateXpath("yep:account")
if accountNodes:
self._account = elements.newElement(
accountNodes[0], previous = self, owner = self)
else:
self._account = "none"
if self._account == "none":
return None
return self._account
def getAccountAbsolutePath(self):
nodes = self.evaluateXpath("yep:account/@src")
if nodes:
accountPath = nodes[0].content
return self.convertPathToAbsolute(accountPath)
else:
return None
def getAuthenticationMethod(self):
account = self.getAccount()
if account is None:
return None
return account.getAuthenticationMethod()
def getClientHostName(self):
nodes = self.evaluateXpath("yep:clientHostName")
if nodes:
return nodes[0].content
else:
return None
def getClientIpAddress(self):
nodes = self.evaluateXpath("yep:clientIpAddress")
if nodes:
return nodes[0].content
else:
return None
def getClientPort(self):
nodes = self.evaluateXpath("yep:clientPort")
if nodes:
return int(nodes[0].content)
else:
return None
def getPublishToken(self):
nodes = self.evaluateXpath("yep:publishToken")
if nodes:
return nodes[0].content not in ("0", "false")
else:
return False
def getToken(self):
localId = self.getDataHolder().localId
if localId.endswith(".xml"):
sessionToken = localId[:-len(".xml")]
else:
sessionToken = localId
return sessionToken
def getUser(self):
account = self.getAccount()
if account is None:
return None
return account.getUser()
def setAccountAbsolutePath(self, accountAbsolutePath):
accountBaseRelativePath = self.convertAbsolutePathToBaseRelative(accountAbsolutePath)
self.setElementAttribute("yep:account", "src", accountBaseRelativePath)
def setClientHostName(self, clientHostName):
self.setElementContent("yep:clientHostName", clientHostName)
self.getDataHolder().isDirty = True
def setClientIpAddress(self, clientIpAddress):
self.setElementContent("yep:clientIpAddress", clientIpAddress)
self.getDataHolder().isDirty = True
def setClientPort(self, clientPort):
self.setElementContent("yep:clientPort", str(clientPort))
self.getDataHolder().isDirty = True
def setPublishToken(self, publishToken):
if publishToken:
publishToken = "true"
else:
publishToken = "false"
self.setElementContent("yep:publishToken", publishToken)
self.getDataHolder().isDirty = True
clientHostName = property(getClientHostName, setClientHostName)
clientIpAddress = property(getClientIpAddress, setClientIpAddress)
clientPort = property(getClientPort, setClientPort)
publishToken = property(getPublishToken, setPublishToken, deletePublishToken)
token = property(getToken)
class SessionHolder(dataholders.XmlHolder):
isDirty = False
def save(self):
super(SessionHolder, self).save()
if self.isDirty:
del self.isDirty
class SessionsHolder(directories.DirectoryHolder):
def getItem(self, sessionToken):
sessionToken = sessionToken + '.xml'
sessionHolder = super(SessionsHolder, self).getItem(sessionToken)
if sessionHolder is None:
return None
session = sessionHolder.getRootElement()
# FIXME: Remove old sessions.
httpRequestHandler = environs.getVar("httpRequestHandler")
clientIpAddress = httpRequestHandler.client_address[0]
if clientIpAddress != session.clientIpAddress and session.clientIpAddress is not None:
logs.info('Tentative use of session "%s" (owned by %s) by %s' % (
sessionToken, session.clientIpAddress, clientIpAddress))
return None
# FIXME: Change session expirationTime and lastTime.
return sessionHolder
def getOrCreateSession():
"""Return the current session (create it if it doesn't exist yet).
Note: Use environs.getVar("session") instead of getOrCreateSession() if you
don't want to create a session when none exists.
"""
session = environs.getVar("session")
if session is None:
rootDataHolder = environs.getVar("rootStation")
sessionsPath = rootDataHolder.getConfigAbsolutePath("yep:sessionsPath")
sessionsDirectoryHolder = SessionsHolder(
pathFragment = sessionsPath, previous = rootDataHolder,
mimeType = "text/xml", isRootElder = True,
containedFileSystem = filesystems.PartialFileSystem(sessionsPath))
sessionFeature = modules.getElementFeature(namespaces.yep.uri, "session")
sessionHolder = sessionFeature.newXmlHolder(sessionsDirectoryHolder)
session = sessionHolder.getRootElement()
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("session", session)
if environs.getVar("canUseCookie"):
baseEnviron.setVar("testCookieSupport", True)
return session
def newSessionHolder(directoryHolder, pathFragment = None, uriPathFragment = None,
temporary = False):
sessionHolder = dataholders.newXmlHolder(
namespaces.yep.uri, "session", directoryHolder, pathFragment = pathFragment,
uriPathFragment = uriPathFragment, temporary = temporary)
session = sessionHolder.getRootElement()
httpRequestHandler = environs.getVar("httpRequestHandler")
clientIpAddress = httpRequestHandler.client_address[0]
session.clientIpAddress = clientIpAddress
session.clientPort = httpRequestHandler.client_address[1]
clientHostName = socket.getfqdn(clientIpAddress)
if clientHostName != clientIpAddress:
session.clientHostName = clientHostName
return sessionHolder
def retrieveSession(sessionToken):
rootDataHolder = environs.getVar('rootStation')
sessionsPath = rootDataHolder.getConfigAbsolutePath("yep:sessionsPath")
sessionsDirectoryHolder = SessionsHolder(
pathFragment = sessionsPath, previous = rootDataHolder,
mimeType = "text/xml", isRootElder = True,
containedFileSystem = filesystems.PartialFileSystem(sessionsPath))
sessionHolder = sessionsDirectoryHolder.getItem(sessionToken)
if sessionHolder is None:
return None
return sessionHolder.getRootElement()
elements.registerElement(
namespaces.yep.uri, "session", Session,
"http://www.entrouvert.org/expression/schemas/Session.xsd",
"http://www.entrouvert.org/expression/descriptions/Session.xml",
SessionHolder, newSessionHolder)
# SessionsHolder.register()