fix: users created via Admin Center never receive password reset emails (#12839)

* Users created via Admin Center never receive password reset emails
Fixes #12733

* fix issue when using registration endpoint

* remove duplicate code path; we now always do that

* remove old test backfill that is not required anymore
This commit is contained in:
Matthias Mair
2026-09-13 13:50:52 +10:00
committed by GitHub
parent 9181097194
commit 6b1a3b899e
4 changed files with 50 additions and 27 deletions
@@ -149,6 +149,7 @@ class RegistrationMixin:
def save_user(self, request, user, form, commit=True):
"""Check if a default group is set in settings."""
user._is_registering = True # marker for email synchronization
# Create the user
user = super().save_user(request, user, form)
@@ -3,8 +3,6 @@
from datetime import timedelta
from unittest.mock import patch
from allauth.account.models import EmailAddress
import part.models
import part.tasks
import stock.models
@@ -24,9 +22,6 @@ class StaleStockNotificationTests(InvenTreeTestCase):
"""Create test data as part of initialization."""
super().setUpTestData()
# Add email address for user
EmailAddress.objects.create(user=cls.user, email='test@testing.com')
# Create test parts
cls.part1 = part.models.Part.objects.create(
name='Test Part 1',
+27 -22
View File
@@ -46,28 +46,6 @@ User.add_to_class('__str__', user_model_str) # Overriding User.__str__
# OVERRIDE END
if settings.LDAP_AUTH:
from django_auth_ldap.backend import populate_user # ty: ignore[unresolved-import]
@receiver(populate_user)
def create_email_address(user, **kwargs):
"""If a django user is from LDAP and has an email attached to it, create an allauth email address for them automatically.
https://django-auth-ldap.readthedocs.io/en/latest/users.html#populating-users
https://django-auth-ldap.readthedocs.io/en/latest/reference.html#django_auth_ldap.backend.populate_user
"""
# User must exist in the database before we can create their EmailAddress. By their recommendation,
# we can just call .save() now
user.save()
# if they got an email address from LDAP, create it now and make it the primary
if (
user.email
and not EmailAddress.objects.filter(user=user, email=user.email).exists()
):
EmailAddress.objects.create(user=user, email=user.email, primary=True)
def default_token():
"""Generate a default value for the token."""
return ApiToken.generate_key()
@@ -647,3 +625,30 @@ def validate_primary_group_on_group_change(sender, instance, action, **kwargs):
if profile.primary_group and profile.primary_group not in instance.groups.all():
profile.primary_group = None
profile.save()
# update allauth user mail
@receiver(post_save, sender=User)
def sync_user_email_address(sender, instance: User, created: bool, **kwargs):
"""Keep the allauth EmailAddress in sync with User email field."""
# Are we currently in the API path of user registration?
if getattr(instance, '_is_registering', False):
return
if isImportingData() or isReadOnlyCommand():
return
if not instance.email:
return
primary_address = EmailAddress.objects.filter(user=instance, primary=True).first()
if primary_address:
if primary_address.email != instance.email:
primary_address.email = instance.email
primary_address.verified = False
primary_address.save()
elif not EmailAddress.objects.filter(user=instance, email=instance.email).exists():
EmailAddress.objects.create(
user=instance, email=instance.email, primary=True, verified=False
)
+22
View File
@@ -6,6 +6,8 @@ from unittest import mock
from django.contrib.auth.models import Group, User
from django.urls import reverse
from allauth.account.models import EmailAddress
from InvenTree.unit_test import InvenTreeAPITestCase
from users.models import ApiToken
from users.ruleset import RULESET_NAMES, get_ruleset_models
@@ -370,6 +372,26 @@ class SuperuserAPITests(InvenTreeAPITestCase):
resp = self.put(url, {'password': 'inventree'}, expected_code=200)
self.assertEqual(resp.data, {})
def test_email_address_sync_signal(self):
"""Test emailadress sync."""
user = User.objects.create(username='start', email='start@example.org')
self.assertTrue(
EmailAddress.objects.filter(
user=user, email='start@example.org', primary=True
).exists()
)
# change should trigger emailaddress update
user.email = 'updated@example.org'
user.save()
self.assertFalse(
EmailAddress.objects.filter(user=user, email='start@example.org').exists()
)
updated = EmailAddress.objects.get(user=user, primary=True)
self.assertEqual(updated.email, 'updated@example.org')
self.assertFalse(updated.verified)
class UserTokenTests(InvenTreeAPITestCase):
"""Tests for user token functionality."""