summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorP. Christeas <p_christ@hol.gr>2010-12-28 15:26:37 +0200
committerP. Christeas <p_christ@hol.gr>2010-12-28 15:26:37 +0200
commit6fa81844d271c9e8e1fc032cdf3d9a694427f0e8 (patch)
treec3fa1169bdb2056f5423987a64dee3baf1522734 /addons
parent6eb0e8e8aa965d33a25d9c226b9389f3deccbea1 (diff)
base_crypt: improve. close cursors, use hashlib, update login date
bzr revid: p_christ@hol.gr-20101228132637-oe86bgxujv17tiz2
Diffstat (limited to 'addons')
-rw-r--r--addons/base_crypt/crypt.py83
1 files changed, 52 insertions, 31 deletions
diff --git a/addons/base_crypt/crypt.py b/addons/base_crypt/crypt.py
index 510f4470d20..ae5f3a3fc55 100644
--- a/addons/base_crypt/crypt.py
+++ b/addons/base_crypt/crypt.py
@@ -66,11 +66,14 @@ def gen_salt( length=8, symbols=ascii_letters + digits ):
# * Poul-Henning Kamp
#TODO: py>=2.6: from hashlib import md5
-import md5
+import hashlib
def encrypt_md5( raw_pw, salt, magic=magic_md5 ):
- hash = md5.new( raw_pw + magic + salt )
- stretch = md5.new( raw_pw + salt + raw_pw).digest()
+ hash = hashlib.md5()
+ hash.update( raw_pw + magic + salt )
+ st = hashlib.md5()
+ st.update( raw_pw + salt + raw_pw)
+ stretch = st.digest()
for i in range( 0, len( raw_pw ) ):
hash.update( stretch[i % 16] )
@@ -87,7 +90,7 @@ def encrypt_md5( raw_pw, salt, magic=magic_md5 ):
saltedmd5 = hash.digest()
for i in range( 1000 ):
- hash = md5.new()
+ hash = hashlib.md5()
if i & 1:
hash.update( raw_pw )
@@ -174,10 +177,12 @@ class users(osv.osv):
cr = pooler.get_db(db).cursor()
return self._login(cr, db, login, password)
except Exception:
- if cr: cr.close()
import logging
logging.getLogger('netsvc').exception('Could not authenticate')
return Exception('Access Denied')
+ finally:
+ if cr is not None:
+ cr.close()
def _login(self, cr, db, login, password):
cr.execute( 'SELECT password, id FROM res_users WHERE login=%s',
@@ -190,6 +195,10 @@ class users(osv.osv):
return False
stored_pw = self.maybe_encrypt(cr, stored_pw, id)
+
+ if not stored_pw:
+ # means couldn't encrypt or user is not active!
+ return False
# Calculate an encrypted password from the user-provided
# password.
@@ -198,10 +207,11 @@ class users(osv.osv):
encrypted_pw = encrypt_md5(password, salt)
# Check if the encrypted password matches against the one in the db.
- cr.execute('select id from res_users where id=%s and password=%s and active',
+ cr.execute('UPDATE res_users SET date=now() ' \
+ 'WHERE id=%s AND password=%s AND active RETURNING id',
(int(id), encrypted_pw.encode('utf-8')))
res = cr.fetchone()
- cr.close()
+ cr.commit()
if res:
return res[0]
@@ -220,20 +230,26 @@ class users(osv.osv):
return True
cr = pooler.get_db(db).cursor()
- if uid not in self._salt_cache.get(db, {}):
- cr.execute( 'SELECT login FROM res_users WHERE id=%s', (uid,) )
- stored_login = cr.fetchone()
- if stored_login:
- stored_login = stored_login[0]
-
- if not self.login(db,stored_login,passwd):
- raise security.ExceptionNoTb('AccessDenied')
-
- salt = self._salt_cache[db][uid]
- cr.execute('SELECT COUNT(*) FROM res_users WHERE id=%s AND password=%s',
- (int(uid), encrypt_md5(passwd, salt)))
- res = cr.fetchone()[0]
- cr.close()
+ try:
+ if uid not in self._salt_cache.get(db, {}):
+ # If we don't have cache, we have to repeat the procedure
+ # through the login function.
+ cr.execute( 'SELECT login FROM res_users WHERE id=%s', (uid,) )
+ stored_login = cr.fetchone()
+ if stored_login:
+ stored_login = stored_login[0]
+
+ res = self._login(cr, db, stored_login, passwd)
+ if not res:
+ raise security.ExceptionNoTb('AccessDenied')
+ else:
+ salt = self._salt_cache[db][uid]
+ cr.execute('SELECT COUNT(*) FROM res_users WHERE id=%s AND password=%s',
+ (int(uid), encrypt_md5(passwd, salt)))
+ res = cr.fetchone()[0]
+ finally:
+ cr.close()
+
if not bool(res):
raise security.ExceptionNoTb('AccessDenied')
@@ -246,18 +262,23 @@ class users(osv.osv):
return bool(res)
def maybe_encrypt(self, cr, pw, id):
- # If the password 'pw' is not encrypted, then encrypt all passwords
- # in the db. Returns the (possibly newly) encrypted password for 'id'.
-
- if pw[0:len(magic_md5)] != magic_md5:
- cr.execute('select id, password from res_users')
+ """ Return the password 'pw', making sure it is encrypted.
+
+ If the password 'pw' is not encrypted, then encrypt all active passwords
+ in the db. Returns the (possibly newly) encrypted password for 'id'.
+ """
+
+ if not pw.startswith(magic_md5):
+ encrypted_res = False
+ cr.execute("SELECT id, password FROM res_users " \
+ "WHERE active=true AND password NOT LIKE '$%'")
+ # Note that we skip all passwords like $.., in anticipation for
+ # more than md5 magic prefixes.
res = cr.fetchall()
for i, p in res:
- encrypted = p
- if p[0:len(magic_md5)] != magic_md5:
- encrypted = encrypt_md5(p, gen_salt())
- cr.execute('update res_users set password=%s where id=%s',
- (encrypted.encode('utf-8'), int(i)))
+ encrypted = encrypt_md5(p, gen_salt())
+ cr.execute('UPDATE res_users SET password=%s where id=%s',
+ (encrypted, i))
if i == id:
encrypted_res = encrypted
cr.commit()