'datadir': args['data_dir'], 'dbname': 'transactions'},
'secure': "False" if args['secure'] == "no" else "True",
'debugging': "True" if args['server_debugging'] else "False"}
+ # Testing database sessions
+ if 'session_type' in args:
+ confopts['sesstype'] = args['session_type']
+ else:
+ confopts['sesstype'] = 'file'
+ if 'session_dburi' in args:
+ confopts['sessopt'] = 'dburi'
+ confopts['sessval'] = args['session_dburi']
+ else:
+ confopts['sessopt'] = 'path'
+ confopts['sessval'] = os.path.join(args['data_dir'], 'sessions')
+ # Whetehr to disable security (for testing)
if args['secure'] == 'no':
confopts['secure'] = "False"
confopts['sslrequiressl'] = ""
from ipsilon.util import page
from ipsilon.root import Root
from jinja2 import Environment, FileSystemLoader
+import ipsilon.util.sessions
def nuke_session_locks():
else:
raise IOError("Configuration file not found")
+cherrypy.lib.sessions.SqlSession = ipsilon.util.sessions.SqlSession
cherrypy.config.update(cfgfile)
nuke_session_locks()
--- /dev/null
+#!/usr/bin/python
+#
+# Copyright (C) 2014 Ipsilon project Contributors, for licensee see COPYING
+
+import base64
+from cherrypy.lib.sessions import Session
+from ipsilon.util.data import SqlStore, SqlQuery
+import threading
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+
+SESSION_COLUMNS = ['id', 'data', 'expiration_time']
+
+
+class SqlSession(Session):
+
+ dburi = None
+ _db = None
+ _proto = 2
+ locks = {}
+
+ @classmethod
+ def setup(cls, **kwargs):
+ """Initialization from cherrypy"""
+
+ for k, v in kwargs.items():
+ if k == 'storage_dburi':
+ cls.dburi = v
+
+ cls._db = SqlStore(cls.dburi)
+
+ def _exists(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ result = q.select({'id': self.id})
+ return True if result.fetchone() else False
+
+ def _load(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ result = q.select({'id': self.id})
+ r = result.fetchone()
+ if r:
+ data = str(base64.b64decode(r[1]))
+ return pickle.loads(data)
+
+ def _save(self, expiration_time):
+ q = None
+ try:
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS, trans=True)
+ q.delete({'id': self.id})
+ data = pickle.dumps((self._data, expiration_time), self._proto)
+ q.insert((self.id, base64.b64encode(data), expiration_time))
+ q.commit()
+ except Exception: # pylint: disable=broad-except
+ if q:
+ q.rollback()
+ raise
+
+ def _delete(self):
+ q = SqlQuery(self._db, 'sessions', SESSION_COLUMNS)
+ q.delete({'id': self.id})
+
+ # copy what RamSession does for now
+ def acquire_lock(self):
+ """Acquire an exclusive lock on the currently-loaded session data."""
+ self.locked = True
+ self.locks.setdefault(self.id, threading.RLock()).acquire()
+
+ def release_lock(self):
+ """Release the lock on the currently-loaded session data."""
+ self.locks[self.id].release()
+ self.locked = False
'admindb': admin_db,
'usersdb': users_db,
'transdb': trans_db,
+ 'sesstype': 'file',
+ 'sessopt': 'path',
+ 'sessval': os.path.join(workdir, 'sessions'),
'secure': 'False'})
conf = os.path.join(workdir, 'ipsilon.conf')
with open(conf, 'w+') as f:
tools.sessions.on = True
tools.sessions.name = "${instance}_ipsilon_session_id"
-tools.sessions.storage_type = "file"
-tools.sessions.storage_path = "${datadir}/sessions"
+tools.sessions.storage_type = "${sesstype}"
+tools.sessions.storage_${sessopt} = "${sessval}"
tools.sessions.path = "/${instance}"
tools.sessions.timeout = 60
tools.sessions.httponly = ${secure}
env=env, preexec_fn=os.setsid)
self.processes.append(p)
p.wait()
- for d in ['adminconfig', 'userprefs', 'transactions']:
+ for d in ['adminconfig', 'userprefs', 'transactions', 'sessions']:
cmd = ['/usr/bin/createdb', '-h', addr, '-p', port, d]
subprocess.check_call(cmd, env=env)
idp_a = {'hostname': '${ADDRESS}:${PORT}',
'database_url': 'postgresql://@127.0.0.10:45432/%(dbname)s',
+ 'session_type': 'sql',
+ 'session_dburi': 'postgresql://@127.0.0.10:45432/sessions',
'admin_user': '${TEST_USER}',
'system_user': '${TEST_USER}',
'instance': '${NAME}',