From 590b67fd71667b59ef26308f7b3a8a475b0021c8 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Tue, 7 Oct 2025 11:41:45 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(backend)=20filter=20invitation=20w?= =?UTF-8?q?ith=20case=20insensitive=20email?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A user can be invited and no control is made on the email case. Then, when a new user is created, we are looking if there are pending invitation and the lookup used is case sensitive. We change it using __iexact which is case insensitive. --- CHANGELOG.md | 1 + src/backend/core/models.py | 2 +- src/backend/core/tests/test_models_users.py | 32 ++++++++++++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b644f79e..15b62c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to - 🐛(frontend) fix attachment download filename #1447 - 🐛(frontend) exclude h4-h6 headings from table of contents #1441 - 🔒(frontend) prevent readers from changing callout emoji #1449 +- 🐛(backend) filter invitation with case insensitive email ## [3.7.0] - 2025-09-12 diff --git a/src/backend/core/models.py b/src/backend/core/models.py index 9b8e13fe..d5e8cf9a 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -221,7 +221,7 @@ class User(AbstractBaseUser, BaseModel, auth_models.PermissionsMixin): Expired invitations are ignored. """ valid_invitations = Invitation.objects.filter( - email=self.email, + email__iexact=self.email, created_at__gte=( timezone.now() - timedelta(seconds=settings.INVITATION_VALIDITY_DURATION) diff --git a/src/backend/core/tests/test_models_users.py b/src/backend/core/tests/test_models_users.py index e7be9267..ff2bbea6 100644 --- a/src/backend/core/tests/test_models_users.py +++ b/src/backend/core/tests/test_models_users.py @@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError import pytest -from core import factories +from core import factories, models pytestmark = pytest.mark.django_db @@ -66,3 +66,33 @@ def test_models_users_sub_validator(sub, is_valid): match=("Enter a valid sub. This value should be ASCII only."), ): user.full_clean() + + +def test_modes_users_convert_valid_invitations(): + """ + The "convert_valid_invitations" method should convert valid invitations to document accesses. + """ + email = "test@example.com" + document = factories.DocumentFactory() + other_document = factories.DocumentFactory() + invitation_document = factories.InvitationFactory(email=email, document=document) + invitation_other_document = factories.InvitationFactory( + email="Test@example.coM", document=other_document + ) + other_email_invitation = factories.InvitationFactory( + email="pre_test@example.com", document=document + ) + + assert document.accesses.count() == 0 + assert other_document.accesses.count() == 0 + + user = factories.UserFactory(email=email) + + assert document.accesses.filter(user=user).count() == 1 + assert other_document.accesses.filter(user=user).count() == 1 + + assert not models.Invitation.objects.filter(id=invitation_document.id).exists() + assert not models.Invitation.objects.filter( + id=invitation_other_document.id + ).exists() + assert models.Invitation.objects.filter(id=other_email_invitation.id).exists()