diff --git a/authentik/core/api/users.py b/authentik/core/api/users.py index b0a635e326..9626cccd5f 100644 --- a/authentik/core/api/users.py +++ b/authentik/core/api/users.py @@ -6,7 +6,6 @@ from json import loads from typing import Any from django.contrib.auth import update_session_auth_hash -from django.contrib.auth.hashers import identify_hasher from django.contrib.auth.models import AnonymousUser, Permission from django.db.transaction import atomic from django.db.utils import IntegrityError @@ -244,7 +243,7 @@ class UserSerializer(ModelSerializer): if password_hash is None: return try: - identify_hasher(password_hash) + User.validate_password_hash(password_hash) except ValueError as exc: LOGGER.warning("Failed to identify password hash format", exc_info=exc) raise ValidationError(_invalid_password_hash_message()) from exc diff --git a/authentik/core/models.py b/authentik/core/models.py index 22bf1a7150..691282af06 100644 --- a/authentik/core/models.py +++ b/authentik/core/models.py @@ -580,6 +580,11 @@ class User(SerializerModel, AttributesMixin, AbstractUser): self.password_change_date = now() return super().set_password(raw_password) + @staticmethod + def validate_password_hash(password_hash: str): + """Validate that the value is a recognized Django password hash.""" + identify_hasher(password_hash) # Raises ValueError if invalid + def set_password_from_hash(self, password_hash: str, signal=True, sender=None, request=None): """Set password directly from a pre-hashed value. @@ -594,7 +599,7 @@ class User(SerializerModel, AttributesMixin, AbstractUser): """ from authentik.core.signals import PASSWORD_SOURCE_HASH - identify_hasher(password_hash) # Raises ValueError if invalid + self.validate_password_hash(password_hash) self._send_password_changed_signal( None, signal,