mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-15 00:42:52 +00:00
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:
@@ -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',
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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."""
|
||||
|
||||
Reference in New Issue
Block a user