auth: delegate legacy local authentication passwords to django (#43094)

This commit is contained in:
Frédéric Péters 2020-05-19 16:32:08 +02:00
parent 92f7c78835
commit fa820fd677
3 changed files with 18 additions and 10 deletions

View File

@ -101,12 +101,12 @@ def do_user_registration(pub, username='foo', password='bar'):
def test_user_registration(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
pub.cfg['passwords'] = {'generate': False}
pub.cfg['passwords'] = {'generate': False, 'hashing_algo': None}
pub.write_cfg()
do_user_registration(pub)
account = PasswordAccount.get('foo')
assert account.password == 'bar' # check it's in clear text
assert account.password == 'bar' # check it's in clear text
def test_user_password_hashing(pub):
@ -161,7 +161,7 @@ def test_user_notification(pub, emails):
user.email = 'admin@localhost'
user.store()
pub.cfg['passwords'] = {'generate': True}
pub.cfg['passwords'] = {'generate': True, 'hashing_algo': None}
pub.write_cfg()
do_user_registration(pub, username='foo@localhost', password=None)

View File

@ -431,7 +431,7 @@ class MethodDirectory(Directory):
if form.is_submitted() and not form.has_errors():
account = PasswordAccount.get(token.username)
account.hashing_algo = passwords_cfg.get('hashing_algo')
account.hashing_algo = passwords_cfg.get('hashing_algo', 'django')
account.set_password(new_password)
account.store()
token.remove_self()
@ -454,7 +454,7 @@ class MethodDirectory(Directory):
except KeyError:
user = None
account.hashing_algo = passwords_cfg.get('hashing_algo')
account.hashing_algo = passwords_cfg.get('hashing_algo', 'django')
account.set_password(str(new_password))
account.store()
token.remove_self()
@ -578,7 +578,7 @@ class MethodDirectory(Directory):
user.store()
account = PasswordAccount(id = username)
account.hashing_algo = passwords_cfg.get('hashing_algo')
account.hashing_algo = passwords_cfg.get('hashing_algo', 'django')
if password:
account.set_password(password)
account.user_id = user.id
@ -733,9 +733,9 @@ class MethodAdminDirectory(Directory):
for key in sorted(HASHING_ALGOS.keys()):
hashing_options.append((key, key.upper()))
form.add(SingleSelectWidget, 'hashing_algo',
title = _('Password Hashing Algorithm'),
value = passwords_cfg.get('hashing_algo'),
options = hashing_options)
title=_('Password Hashing Algorithm'),
value=passwords_cfg.get('hashing_algo', 'django'),
options=hashing_options)
form.add_submit('submit', _('Submit'))
form.add_submit('cancel', _('Cancel'))

View File

@ -16,6 +16,7 @@
import hashlib
from django.contrib.auth.hashers import check_password, make_password
from django.utils.encoding import force_bytes, force_text
from quixote import get_publisher
@ -23,6 +24,9 @@ from wcs.qommon import force_str
from ..storage import StorableObject
HASHING_ALGOS = {
# by default delegate to django password handling
'django': None,
# legacy hashing algorithms, to check ancient passwords
'sha': hashlib.sha1,
'md5': hashlib.md5,
'sha256': hashlib.sha256,
@ -35,7 +39,7 @@ class PasswordAccount(StorableObject):
id = None # id is username
password = None
hashing_algo = None
hashing_algo = 'django' # delegate
awaiting_confirmation = False
awaiting_moderation = False
@ -62,11 +66,15 @@ class PasswordAccount(StorableObject):
def is_password_ok(self, password):
if self.hashing_algo is None:
return (self.password == password)
elif self.hashing_algo == 'django':
return check_password(password, self.password)
else:
return (self.password == force_str(HASHING_ALGOS.get(self.hashing_algo)(force_bytes(password)).hexdigest()))
def set_password(self, password):
if self.hashing_algo is None:
self.password = password
elif self.hashing_algo == 'django':
self.password = make_password(password)
else:
self.password = force_str(HASHING_ALGOS.get(self.hashing_algo)(force_bytes(password)).hexdigest())