From 77a0c1df8017cb0ae0f333cb16eca02b1ee27b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 25 Aug 2009 19:15:50 +0200 Subject: [PATCH] Move login test in res.user --- CHANGELOG | 1 + trytond/res/user.py | 51 +++++++++++++++++++++++++++++++++++++-- trytond/security.py | 58 ++++++++++++++++----------------------------- 3 files changed, 71 insertions(+), 39 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fc3e12949d..b272aa7380 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Move login test in res.user * Rename osv into model on workflow * Add logout method * Move BrowseRecord cache onto the cursor diff --git a/trytond/res/user.py b/trytond/res/user.py index 9c87f6fbb0..81af93049c 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -10,6 +10,11 @@ from trytond.backend import TableHandler from trytond.security import get_connections import string import random +try: + import hashlib +except ImportError: + hashlib = None + import sha class User(ModelSQL, ModelView): @@ -137,7 +142,10 @@ class User(ModelSQL, ModelView): def create(self, cursor, user, vals, context=None): vals = self._convert_vals(cursor, user, vals, context=context) - return super(User, self).create(cursor, user, vals, context=context) + res = super(User, self).create(cursor, user, vals, context=context) + # Restart the cache for _get_login + self._get_login(cursor.dbname) + return res def write(self, cursor, user, ids, vals, context=None): vals = self._convert_vals(cursor, user, vals, context=context) @@ -146,6 +154,8 @@ class User(ModelSQL, ModelView): self.pool.get('ir.rule').domain_get(cursor.dbname) # Restart the cache for get_groups self.get_groups(cursor.dbname) + # Restart the cache for _get_login + self._get_login(cursor.dbname) # Restart the cache for get_preferences self.get_preferences(cursor.dbname) # Restart the cache of check @@ -163,7 +173,10 @@ class User(ModelSQL, ModelView): ids = [ids] if 0 in ids: self.raise_user_error(cursor, 'rm_root', context=context) - return super(User, self).delete(cursor, user, ids, context=context) + res = super(User, self).delete(cursor, user, ids, context=context) + # Restart the cache for _get_login + self._get_login(cursor.dbname) + return res def read(self, cursor, user, ids, fields_names=None, context=None): res = super(User, self).read(cursor, user, ids, fields_names=fields_names, @@ -333,6 +346,40 @@ class User(ModelSQL, ModelView): get_groups = Cache('res_user.get_groups')(get_groups) + def _get_login(self, cursor, user, login, context=None): + cursor.execute('SELECT id, password, salt ' \ + 'FROM "' + self._table + '" ' + 'WHERE login = %s AND active', (login,)) + res = cursor.fetchone() + if not res: + return None, None, None + return res + _get_login = Cache('res_user._get_login')(_get_login) + + def get_login(self, cursor, user, login, password, context=None): + ''' + Return user id if password matches + + :param cursor: the database cursor + :param user: the user id + :param login: the login name + :param password: the password + :param context: the context + :return: integer + ''' + user_id, user_password, salt = self._get_login(cursor, user, + login, context=context) + if not user_id: + return 0 + password += salt or '' + if hashlib: + password_sha = hashlib.sha1(password).hexdigest() + else: + password_sha = sha.new(password).hexdigest() + if password_sha == user_password: + return user_id + return 0 + User() diff --git a/trytond/security.py b/trytond/security.py index fda3415e95..a6b2129b68 100644 --- a/trytond/security.py +++ b/trytond/security.py @@ -2,12 +2,8 @@ #this repository contains the full copyright notices and license terms. from trytond.backend import Database from trytond.session import Session +from trytond.pool import Pool from config import CONFIG -try: - import hashlib -except ImportError: - hashlib = None - import sha import time @@ -16,41 +12,29 @@ _USER_TRY = {} def login(dbname, loginname, password, cache=True): _USER_TRY.setdefault(dbname, {}) + _USER_TRY[dbname].setdefault(loginname, 0) database = Database(dbname).connect() cursor = database.cursor() - cursor.execute('SELECT id, password, active, salt FROM res_user ' - 'WHERE login = %s', (loginname,)) - res = cursor.fetchone() - if res: - cursor.close() - user_id = res[0] - if user_id == 0: - return False - _USER_TRY[dbname].setdefault(user_id, 0) - # Add salt - password += res[3] or '' - if hashlib: - password_sha = hashlib.sha1(password).hexdigest() - else: - password_sha = sha.new(password).hexdigest() - if res[1] == password_sha and res[2]: - _USER_TRY[dbname][user_id] = 0 - if cache: - _USER_CACHE.setdefault(dbname, {}) - _USER_CACHE[dbname].setdefault(user_id, []) - session = Session(user_id) - session.name = loginname - _USER_CACHE[dbname][user_id].append(session) - return (user_id, session.session) - else: - return user_id - time.sleep(2 ** _USER_TRY[dbname][user_id]) - _USER_TRY[dbname][user_id] += 1 - return False + database_list = Pool.database_list() + pool = Pool(dbname) + if not dbname in database_list: + pool.init() + user_obj = pool.get('res.user') + user_id = user_obj.get_login(cursor, 0, loginname, password) cursor.close() - _USER_TRY[dbname].setdefault(0, 0) - time.sleep(2 ** _USER_TRY[dbname][0]) - _USER_TRY[dbname][0] += 1 + if user_id: + _USER_TRY[dbname][loginname] = 0 + if cache: + _USER_CACHE.setdefault(dbname, {}) + _USER_CACHE[dbname].setdefault(user_id, []) + session = Session(user_id) + session.name = loginname + _USER_CACHE[dbname][user_id].append(session) + return (user_id, session.session) + else: + return user_id + time.sleep(2 ** _USER_TRY[dbname][loginname]) + _USER_TRY[dbname][loginname] += 1 return False def logout(dbname, user, session):