base_crypt: improve. close cursors, use hashlib, update login date
bzr revid: p_christ@hol.gr-20101228132637-oe86bgxujv17tiz2
This commit is contained in:
parent
6eb0e8e8aa
commit
6fa81844d2
|
@ -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')
|
||||
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()
|
||||
|
||||
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()
|
||||
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'.
|
||||
""" 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 pw[0:len(magic_md5)] != magic_md5:
|
||||
cr.execute('select id, password from res_users')
|
||||
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()
|
||||
|
|
Loading…
Reference in New Issue