269 lines
9.3 KiB
Python
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()
|