1
0
mirror of https://github.com/django/django.git synced 2025-03-12 10:22:37 +00:00

Fixed #36087 -- Supported password reset on a custom user model with a composite primary key.

This commit is contained in:
Sarah Boyce 2025-01-13 12:01:49 +01:00
parent d83fb782d3
commit 23c6effac0
5 changed files with 37 additions and 4 deletions

View File

@ -478,11 +478,12 @@ class PasswordResetForm(forms.Form):
email_field_name = UserModel.get_email_field_name()
for user in self.get_users(email):
user_email = getattr(user, email_field_name)
user_pk_bytes = force_bytes(UserModel._meta.pk.value_to_string(user))
context = {
"email": user_email,
"domain": domain,
"site_name": site_name,
"uid": urlsafe_base64_encode(force_bytes(user.pk)),
"uid": urlsafe_base64_encode(user_pk_bytes),
"user": user,
"token": token_generator.make_token(user),
"protocol": "https" if use_https else "http",

View File

@ -301,7 +301,8 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
try:
# urlsafe_base64_decode() decodes to bytestring
uid = urlsafe_base64_decode(uidb64).decode()
user = UserModel._default_manager.get(pk=uid)
pk = UserModel._meta.pk.to_python(uid)
user = UserModel._default_manager.get(pk=pk)
except (
TypeError,
ValueError,

View File

@ -1,5 +1,10 @@
from .custom_permissions import CustomPermissionsUser
from .custom_user import CustomUser, CustomUserWithoutIsActiveField, ExtensionUser
from .custom_user import (
CustomUser,
CustomUserCompositePrimaryKey,
CustomUserWithoutIsActiveField,
ExtensionUser,
)
from .invalid_models import CustomUserNonUniqueUsername
from .is_active import IsActiveTestUser1
from .minimal import MinimalUser
@ -17,6 +22,7 @@ __all__ = (
"CustomEmailField",
"CustomPermissionsUser",
"CustomUser",
"CustomUserCompositePrimaryKey",
"CustomUserNonUniqueUsername",
"CustomUserWithFK",
"CustomUserWithM2M",

View File

@ -119,6 +119,19 @@ class CustomUserWithoutIsActiveField(AbstractBaseUser):
USERNAME_FIELD = "username"
class CustomUserCompositePrimaryKey(AbstractBaseUser):
pk = models.CompositePrimaryKey("email", "date_of_birth")
email = models.EmailField(verbose_name="email address", max_length=255, unique=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
date_of_birth = models.DateField()
custom_objects = CustomUserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["date_of_birth"]
# The extension user is a simple extension of the built-in user class,
# adding a required date_of_birth field. This allows us to check for
# any hard references to the name "User" in forms/handlers etc.

View File

@ -38,7 +38,7 @@ from django.urls import NoReverseMatch, reverse, reverse_lazy
from django.utils.http import urlsafe_base64_encode
from .client import PasswordResetConfirmClient
from .models import CustomUser, UUIDUser
from .models import CustomUser, CustomUserCompositePrimaryKey, UUIDUser
from .settings import AUTH_TEMPLATES
@ -540,6 +540,18 @@ class CustomUserPasswordResetTest(AuthViewsTestCase):
self.assertRedirects(response, "/reset/done/")
@override_settings(AUTH_USER_MODEL="auth_tests.CustomUserCompositePrimaryKey")
class CustomUserCompositePrimaryKeyPasswordResetTest(CustomUserPasswordResetTest):
@classmethod
def setUpTestData(cls):
cls.u1 = CustomUserCompositePrimaryKey.custom_objects.create(
email="staffmember@example.com",
date_of_birth=datetime.date(1976, 11, 8),
)
cls.u1.set_password("password")
cls.u1.save()
@override_settings(AUTH_USER_MODEL="auth_tests.UUIDUser")
class UUIDUserPasswordResetTest(CustomUserPasswordResetTest):
def _test_confirm_start(self):