convert user password at login if it's not using the right scheme

This commit is contained in:
Anthony Bourguignon
2018-10-05 14:48:01 +02:00
parent c34f3dc2c2
commit 1d83a3b706
2 changed files with 45 additions and 0 deletions
+28
View File
@@ -12,6 +12,7 @@ from django.test import override_settings
from django.urls import reverse
from modoboa.lib.tests import NO_SMTP, ModoTestCase
from modoboa.core.password_hashers import get_password_hasher
from .. import factories, models
try:
@@ -67,6 +68,33 @@ class AuthenticationTestCase(ModoTestCase):
self.assertEqual(response.status_code, 302)
self.assertTrue(response.url.endswith(reverse("core:dashboard")))
def test_password_scheme(self):
"""Validate password scheme changes."""
url = reverse("core:parameters")
username = "user@test.com"
password = "toto"
data = {"username": username, "password": password}
user = models.User.objects.get(username=username)
pw_hash = get_password_hasher('fallback_scheme')()
self.client.logout()
self.set_global_parameter("password_scheme", "sha512crypt")
response = self.client.post(reverse("core:login"), data)
user.refresh_from_db()
self.assertTrue(user.password.startswith("{SHA512-CRYPT}"))
self.client.logout()
self.set_global_parameter("password_scheme", "sha256")
response = self.client.post(reverse("core:login"), data)
user.refresh_from_db()
self.assertTrue(user.password.startswith("{SHA256}"))
self.client.logout()
self.set_global_parameter("password_scheme", "fallback_scheme")
response = self.client.post(reverse("core:login"), data)
user.refresh_from_db()
self.assertTrue(user.password.startswith(pw_hash.scheme))
class PasswordResetTestCase(ModoTestCase):
"""Test password reset service."""
+17
View File
@@ -17,6 +17,8 @@ from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from modoboa.core import forms
from modoboa.core.password_hashers import get_password_hasher
from modoboa.parameters import tools as param_tools
from .. import signals
from .base import find_nextlocation
@@ -33,6 +35,21 @@ def dologin(request):
user = authenticate(username=form.cleaned_data["username"],
password=form.cleaned_data["password"])
if user and user.is_active:
# check if password scheme is correct
scheme = param_tools.get_global_parameter("password_scheme",
raise_exception=False)
# use SHA512CRYPT as default fallback
if scheme is None:
pwhash = get_password_hasher('sha512crypt')()
else:
pwhash = get_password_hasher(scheme)()
if not user.password.startswith(pwhash.scheme):
logging.info(
_("Password scheme mismatch. Updating %s password") % user.username
)
user.set_password(form.cleaned_data["password"])
user.save()
login(request, user)
if not form.cleaned_data["rememberme"]:
request.session.set_expiry(0)