Merge pull request #3933 from modoboa/fix/password-check

Use django authentication function to check password.
This commit is contained in:
Antoine Nguyen
2026-02-20 22:30:32 +01:00
committed by GitHub
5 changed files with 23 additions and 12 deletions
+11 -3
View File
@@ -10,6 +10,8 @@ from django.core.cache import cache
from django.test import override_settings
from django.urls import reverse
from django.contrib.auth import authenticate
from rest_framework.authtoken.models import Token
from reversion.models import Version
@@ -461,13 +463,17 @@ class AccountAPITestCase(ModoAPITestCase):
account.refresh_from_db()
account.mailbox.refresh_from_db()
self.assertEqual(account.email, account.mailbox.full_address)
self.assertTrue(account.check_password("Toto1234"))
self.assertIsNot(
authenticate(username=account.username, password="Toto1234"), None
)
del data["password"]
response = self.client.put(url, data, format="json")
self.assertEqual(response.status_code, 200)
account.refresh_from_db()
self.assertTrue(account.check_password("Toto1234"))
self.assertIsNot(
authenticate(username=account.username, password="Toto1234"), None
)
def test_update_account_with_no_mailbox(self):
"""Try to disable an account."""
@@ -577,7 +583,9 @@ class AccountAPITestCase(ModoAPITestCase):
)
self.assertEqual(response.status_code, 200)
account.refresh_from_db()
self.assertTrue(account.check_password("Toto1234"))
self.assertIsNot(
authenticate(username=account.username, password="Toto1234"), None
)
@mock.patch("ovh.Client.get")
@mock.patch("ovh.Client.post")
+3 -1
View File
@@ -8,6 +8,8 @@ from django.core.management import call_command
from django.core.management.base import CommandError
from django.urls import reverse
from django.contrib.auth import authenticate
from modoboa.core import factories as core_factories
from modoboa.core.models import User
from modoboa.lib.tests import ModoAPITestCase
@@ -335,4 +337,4 @@ alias; alias1@test.com; True; user1@test.com
)
call_command("modo", "import", "--crypt-passwords", test_file)
user = User.objects.get(username="user1@test.com")
self.assertTrue(user.check_password("toto"))
self.assertIsNot(authenticate(username=user.username, password="toto"), None)
+5 -5
View File
@@ -2,7 +2,7 @@
import logging
from django.contrib.auth import password_validation
from django.contrib.auth import authenticate, password_validation
from django.core.exceptions import ValidationError
from django.utils.html import escape
from django.utils.translation import gettext as _
@@ -31,7 +31,7 @@ class AccountPasswordSerializer(serializers.ModelSerializer):
"""Check password."""
authentication_type = param_tools.get_global_parameter("authentication_type")
if authentication_type != "ldap":
check = self.instance.check_password(value)
check = authenticate(username=self.instance.username, password=value)
else:
from django_auth_ldap.backend import LDAPBackend
@@ -80,9 +80,9 @@ class CheckPasswordTFASerializer(serializers.Serializer):
password = serializers.CharField()
def validate_password(self, value):
user = self.context["user"]
if not user.check_password(value):
def validate_password(self, value: str) -> str:
user: models.User = self.context["user"]
if not authenticate(username=user.username, password=value):
msg = _(
"Failed TFA settings editing attempt from '%(addr)s' as user '%(user)s'"
) % {
+2 -2
View File
@@ -6,7 +6,7 @@ import oath
from django.conf import settings
from django.db.models import Q
from django.contrib.auth import password_validation
from django.contrib.auth import authenticate, password_validation
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.tokens import default_token_generator
from django.core.mail import send_mail
@@ -434,7 +434,7 @@ class CheckPasswordSerializer(serializers.Serializer):
def validate_password(self, value):
user = self.context["user"]
if not user.check_password(value):
if not authenticate(username=user.username, password=value):
raise serializers.ValidationError(_("Invalid password"))
return value
+2 -1
View File
@@ -3,6 +3,7 @@
import imaplib
import ssl
from django.contrib.auth import authenticate
from django.utils.encoding import smart_bytes, smart_str
from django.utils.translation import gettext as _
@@ -94,7 +95,7 @@ class IMAPBackend:
# No migration => either someone else account, or
# migration is done
return None
if not user.check_password(password):
if not authenticate(username=user.username, password=password):
# User may have changed its password on modoboa
# Remote password and local now differs
# We block the connection in that case