Mercurial > p > roundup > code
diff roundup/backends/sessions_rdbms.py @ 6823:fe0091279f50
Refactor session db logging and key generation for sessions/otks
While I was working on the redis sessiondb stuff, I noticed that
log_wanrning, get_logger ... was duplicated. Also there was code to
generate a unique key for otks that was duplicated.
Changes:
creating new sessions_common.py and SessionsCommon class to provide
methods:
log_warning, log_info, log_debug, get_logger, getUniqueKey
getUniqueKey method is closer to the method used to make
session keys in client.py.
sessions_common.py now report when random_.py chooses a weak
random number generator. Removed same from rest.py.
get_logger reconciles all logging under
roundup.hyperdb.backends.<name of BasicDatabase class>
some backends used to log to root logger.
have BasicDatabase in other sessions_*.py modules inherit from
SessionCommon.
change logging to use log_* methods.
In addition:
remove unused imports reported by flake8 and other formatting
changes
modify actions.py, rest.py, templating.py to use getUniqueKey
method.
add tests for new methods
test_redis_session.py
swap out ModuleNotFoundError for ImportError to prevent crash in
python2 when redis is not present.
allow injection of username:password or just password into redis
connection URL. set pytest_redis_pw envirnment variable to password
or user:password when running test.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 07 Aug 2022 01:51:11 -0400 |
| parents | 375d40a9e730 |
| children | ee17f62c8341 |
line wrap: on
line diff
--- a/roundup/backends/sessions_rdbms.py Sun Aug 07 01:26:30 2022 -0400 +++ b/roundup/backends/sessions_rdbms.py Sun Aug 07 01:51:11 2022 -0400 @@ -5,67 +5,70 @@ class. It's now also used for One Time Key handling too. """ __docformat__ = 'restructuredtext' -import os, time, logging +import time from roundup.anypy.html import html_escape as escape +from roundup.backends.sessions_common import SessionCommon -class BasicDatabase: + +class BasicDatabase(SessionCommon): ''' Provide a nice encapsulation of an RDBMS table. Keys are id strings, values are automatically marshalled data. ''' name = None + def __init__(self, db): self.db = db self.conn, self.cursor = self.db.sql_open_connection() def clear(self): - self.cursor.execute('delete from %ss'%self.name) + self.cursor.execute('delete from %ss' % self.name) def exists(self, infoid): n = self.name - self.cursor.execute('select count(*) from %ss where %s_key=%s'%(n, - n, self.db.arg), (infoid,)) + self.cursor.execute('select count(*) from %ss where %s_key=%s' % + (n, n, self.db.arg), (infoid,)) return int(self.cursor.fetchone()[0]) _marker = [] + def get(self, infoid, value, default=_marker): n = self.name - self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n, - n, n, self.db.arg), (infoid,)) + self.cursor.execute('select %s_value from %ss where %s_key=%s' % + (n, n, n, self.db.arg), (infoid,)) res = self.cursor.fetchone() if not res: if default != self._marker: return default - raise KeyError('No such %s "%s"'%(self.name, escape(infoid))) + raise KeyError('No such %s "%s"' % (self.name, escape(infoid))) values = eval(res[0]) return values.get(value, None) def getall(self, infoid): n = self.name - self.cursor.execute('select %s_value from %ss where %s_key=%s'%(n, - n, n, self.db.arg), (infoid,)) + self.cursor.execute('select %s_value from %ss where %s_key=%s' % + (n, n, n, self.db.arg), (infoid,)) res = self.cursor.fetchone() if not res: - raise KeyError('No such %s "%s"'%(self.name, escape (infoid))) + raise KeyError('No such %s "%s"' % (self.name, escape(infoid))) return eval(res[0]) def set(self, infoid, **newvalues): """ Store all newvalues under key infoid with a timestamp in database. - If newvalues['__timestamp'] exists and is representable as a floating point number - (i.e. could be generated by time.time()), that value is used for the <name>_time - column in the database. + If newvalues['__timestamp'] exists and is representable as + a floating point number (i.e. could be generated by time.time()), + that value is used for the <name>_time column in the database. """ c = self.cursor n = self.name a = self.db.arg - c.execute('select %s_value from %ss where %s_key=%s'% \ - (n, n, n, a), - (infoid,)) + c.execute('select %s_value from %ss where %s_key=%s' % + (n, n, n, a), (infoid,)) res = c.fetchone() - timestamp=time.time() + timestamp = time.time() if res: values = eval(res[0]) else: @@ -85,43 +88,43 @@ values.update(newvalues) if res: sql = ('update %ss set %s_value=%s, %s_time=%s ' - 'where %s_key=%s'%(n, n, a, n, a, n, a)) + 'where %s_key=%s' % (n, n, a, n, a, n, a)) args = (repr(values), timestamp, infoid) else: sql = 'insert into %ss (%s_key, %s_time, %s_value) '\ - 'values (%s, %s, %s)'%(n, n, n, n, a, a, a) + 'values (%s, %s, %s)' % (n, n, n, n, a, a, a) args = (infoid, timestamp, repr(values)) c.execute(sql, args) def list(self): c = self.cursor n = self.name - c.execute('select %s_key from %ss'%(n, n)) + c.execute('select %s_key from %ss' % (n, n)) return [res[0] for res in c.fetchall()] def destroy(self, infoid): - self.cursor.execute('delete from %ss where %s_key=%s'%(self.name, - self.name, self.db.arg), (infoid,)) + self.cursor.execute('delete from %ss where %s_key=%s' % + (self.name, self.name, self.db.arg), (infoid,)) def updateTimestamp(self, infoid): """ don't update every hit - once a minute should be OK """ now = time.time() - self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s - and %s_time < %s'''%(self.name, self.name, self.db.arg, - self.name, self.db.arg, self.name, self.db.arg), - (now, infoid, now-60)) + self.cursor.execute('''update %ss set %s_time=%s where %s_key=%s ''' + '''and %s_time < %s''' % + (self.name, self.name, self.db.arg, self.name, + self.db.arg, self.name, self.db.arg), + (now, infoid, now-60)) def clean(self): ''' Remove session records that haven't been used for a week. ''' now = time.time() week = 60*60*24*7 old = now - week - self.cursor.execute('delete from %ss where %s_time < %s'%(self.name, - self.name, self.db.arg), (old, )) + self.cursor.execute('delete from %ss where %s_time < %s' % + (self.name, self.name, self.db.arg), (old, )) def commit(self): - logger = logging.getLogger('roundup.hyperdb.backend') - logger.info('commit %s' % self.name) + self.log_info('commit %s' % self.name) self.conn.commit() self.cursor = self.conn.cursor() @@ -136,9 +139,11 @@ def close(self): self.conn.close() + class Sessions(BasicDatabase): name = 'session' + class OneTimeKeys(BasicDatabase): name = 'otk'
