From 716f60afe9f87dfed108a90701c8b8d6e7cb8da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 11 Dec 2008 17:05:52 +0100 Subject: [PATCH] Use a Session object for user instead of just an integer --- trytond/osv/orm.py | 2 +- trytond/security.py | 44 +++++++++++++++++++++++++---------- trytond/sql_db.py | 9 ++++--- trytond/web_service/object.py | 8 +++---- trytond/web_service/report.py | 2 +- trytond/web_service/wizard.py | 6 ++--- 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/trytond/osv/orm.py b/trytond/osv/orm.py index 4068967755..1ac4ab9ec9 100644 --- a/trytond/osv/orm.py +++ b/trytond/osv/orm.py @@ -678,7 +678,7 @@ class ORM(object): def default_create_uid(self, cursor, user, context=None): "Default value for uid field" - return user + return int(user) def default_create_date(self, cursor, user, context=None): "Default value for create_date field" diff --git a/trytond/security.py b/trytond/security.py index aec7829afd..bc1586770e 100644 --- a/trytond/security.py +++ b/trytond/security.py @@ -1,10 +1,30 @@ -#This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. +#This file is part of Tryton. The COPYRIGHT file at the top level of +#this repository contains the full copyright notices and license terms. import pooler from config import CONFIG import sha import time import random + +class Session(int): + + def __init__(self, x): + super(Session, self).__init__(x) + self.__data = { + 'session': str(random.random()), + 'timestamp': time.time(), + } + + def __getattr__(self, name): + return self.__data[name] + + def __getitem__(self, name): + return self.__data[name] + + def reset_timestamp(self): + self.__data['timestamp'] = time.time() + _USER_CACHE = {} def login(dbname, loginname, password, cache=True): @@ -21,11 +41,10 @@ def login(dbname, loginname, password, cache=True): return False if cache: _USER_CACHE.setdefault(dbname, {}) - timestamp = time.time() - session = str(random.random()) _USER_CACHE[dbname].setdefault(user_id, []) - _USER_CACHE[dbname][user_id].append((timestamp, session)) - return (user_id, session) + session = Session(user_id) + _USER_CACHE[dbname][user_id].append(session) + return (user_id, session.session) else: return user_id else: @@ -41,20 +60,21 @@ def check(dbname, user, session, outdate_timeout=True): if user == 0: raise Exception('AccessDenied') result = False + now = time.time() + timeout = int(CONFIG['session_timeout']) if _USER_CACHE.get(dbname, {}).has_key(user): to_del = [] - for i, (timestamp, real_session) \ + for i, real_session \ in enumerate(_USER_CACHE[dbname][user]): - if abs(timestamp - time.time()) < int(CONFIG['session_timeout']): - if real_session == session: + if abs(real_session.timestamp - now) < timeout: + if real_session.session == session: if outdate_timeout: - _USER_CACHE[dbname][user][i] = \ - (time.time(), real_session) - result = True + real_session.reset_timestamp() + result = real_session else: to_del.insert(0, i) for i in to_del: del _USER_CACHE[dbname][user][i] if result: - return True + return result raise Exception('NotLogged') diff --git a/trytond/sql_db.py b/trytond/sql_db.py index c21fdd7c86..7cd9d47394 100644 --- a/trytond/sql_db.py +++ b/trytond/sql_db.py @@ -1,6 +1,7 @@ -#This file is part of Tryton. The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. +#This file is part of Tryton. The COPYRIGHT file at the top level of +#this repository contains the full copyright notices and license terms. from psycopg2.pool import ThreadedConnectionPool -from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE, cursor +from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE, cursor, AsIs from psycopg2 import IntegrityError import psycopg2 import re @@ -10,6 +11,7 @@ import zipfile import version from config import CONFIG import logging +from trytond.security import Session RE_FROM = re.compile('.* from "?([a-zA-Z_0-9]+)"?.*$') RE_INTO = re.compile('.* into "?([a-zA-Z_0-9]+)"?.*$') @@ -208,7 +210,8 @@ def init_db(cursor): (module_id, dependency)) psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) - +psycopg2.extensions.register_adapter(Session, + psycopg2.extensions.AsIs) def table_exist(cursor, table_name): diff --git a/trytond/web_service/object.py b/trytond/web_service/object.py index 5ed9e4b041..19429933cb 100644 --- a/trytond/web_service/object.py +++ b/trytond/web_service/object.py @@ -14,7 +14,7 @@ class Object(Service): def exec_workflow(self, database, user, session, object_name, method, object_id, *args): - security.check(database, user, session) + user = security.check(database, user, session) Cache.clean(database) service = LocalService("object_proxy") res = service.exec_workflow(database, user, object_name, method, @@ -23,16 +23,16 @@ class Object(Service): def execute(self, database, user, session, object_name, method, *args): if object_name == 'res.request' and method == 'request_get': - security.check(database, user, session, False) + user = security.check(database, user, session, False) else: - security.check(database, user, session) + user = security.check(database, user, session) Cache.clean(database) service = LocalService("object_proxy") res = service.execute(database, user, object_name, method, *args) return res def obj_list(self, database, user, session): - security.check(database, user, session) + user = security.check(database, user, session) Cache.clean(database) service = LocalService("object_proxy") res = service.obj_list() diff --git a/trytond/web_service/report.py b/trytond/web_service/report.py index cddec6e0be..712ce2576e 100644 --- a/trytond/web_service/report.py +++ b/trytond/web_service/report.py @@ -13,7 +13,7 @@ class Report(Service): def execute(self, database, user, passwd, report_name, ids, datas, context=None): - security.check(database, user, passwd) + user = security.check(database, user, passwd) Cache.clean(database) report = LocalService('report_proxy') return report.execute(database, user, report_name, ids, datas, context) diff --git a/trytond/web_service/wizard.py b/trytond/web_service/wizard.py index d3c6d14e60..f4fb868aae 100644 --- a/trytond/web_service/wizard.py +++ b/trytond/web_service/wizard.py @@ -27,7 +27,7 @@ class Wizard(Service): self.wiz_datas[wiz_id], action, context) def create(self, database, user, passwd, wiz_name, datas=None): - security.check(database, user, passwd) + user = security.check(database, user, passwd) Cache.clean(database) self.lock.acquire() wiz_id = 0 @@ -42,7 +42,7 @@ class Wizard(Service): return wiz_id def execute(self, database, user, passwd, wiz_id, datas, *args): - security.check(database, user, passwd) + user = security.check(database, user, passwd) Cache.clean(database) if wiz_id in self.wiz_uid: if self.wiz_uid[wiz_id] == user: @@ -53,7 +53,7 @@ class Wizard(Service): raise Exception, 'WizardNotFound' def delete(self, database, user, passwd, wiz_id): - security.check(database, user, passwd) + user = security.check(database, user, passwd) Cache.clean(database) if wiz_id in self.wiz_uid: if self.wiz_uid[wiz_id] == user: