fix(backend): reject duplicate email when creating a user via the API (#13100)

UserCreateSerializer did not check whether the email address was
already in use (signup does, via allauth). Email based flows such as
the login link look users up by email and silently send nothing when
more than one user matches, while the API still reports success.

Two existing tests reused one email for several users; give them
distinct addresses.
This commit is contained in:
Oren authored and GitHub committed 2026-10-26 11:28:40 +11:00
1 parent 8de2ed3b47
commit bab82bf808
2 files changed
+39 -3

No files matched your search

@@ -544,6 +544,19 @@ class UserCreateSerializer(ExtendedUserSerializer):
_('You do not have permission to create users')
)
# Email-based flows (password reset, login link) look users up by email,
# and fail silently if more than one user has the same address
if email := attrs.get('email'):
from allauth.account.models import EmailAddress
if (
User.objects.filter(email__iexact=email).exists()
or EmailAddress.objects.filter(email__iexact=email).exists()
):
raise serializers.ValidationError({
'email': _('A user with this email address already exists')
})
# Generate a random password
password = make_random_password(length=14)
attrs.update({'password': password})
+26 -3
View File
@@ -131,11 +131,24 @@ class UserAPITests(InvenTreeAPITestCase):
).exists()
)
# A second user with the same email address (any case) is rejected
response = self.post(
url,
data={**data, 'username': 'test2', 'email': 'AA@example.org'},
expected_code=400,
)
self.assertIn('email', response.data)
# Try to adjust the 'is_superuser' field
# Only a "superuser" can set this field
response = self.post(
url,
data={**data, 'username': 'Superuser', 'is_superuser': True},
data={
**data,
'username': 'Superuser',
'email': 'su@example.org',
'is_superuser': True,
},
expected_code=403,
)
@@ -147,7 +160,12 @@ class UserAPITests(InvenTreeAPITestCase):
response = self.post(
url,
data={**data, 'username': 'Superuser', 'is_superuser': True},
data={
**data,
'username': 'Superuser',
'email': 'su@example.org',
'is_superuser': True,
},
expected_code=201,
)
@@ -186,7 +204,12 @@ class UserAPITests(InvenTreeAPITestCase):
# Creating a user without specifying groups must still work
response = self.post(
url,
data={**data, 'username': 'ungrouped', 'group_ids': []},
data={
**data,
'username': 'ungrouped',
'email': 'ungrouped@example.org',
'group_ids': [],
},
expected_code=201,
)
self.assertEqual(response.data['groups'], [])