lowercase emails on add user to domain; case insensitive match on matching DomainInvitations on login; test cases

This commit is contained in:
David Kennedy 2023-12-14 07:44:31 -05:00
parent d9237c2927
commit e36351d21e
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
4 changed files with 52 additions and 1 deletions

View file

@ -28,6 +28,17 @@ class DomainAddUserForm(forms.Form):
email = forms.EmailField(label="Email") email = forms.EmailField(label="Email")
def clean(self):
"""clean form data by lowercasing email"""
cleaned_data = super().clean()
# Lowercase the value of the 'email' field
email_value = cleaned_data.get("email")
if email_value:
cleaned_data["email"] = email_value.lower()
return cleaned_data
class DomainNameserverForm(forms.Form): class DomainNameserverForm(forms.Form):
"""Form for changing nameservers.""" """Form for changing nameservers."""

View file

@ -101,7 +101,7 @@ class User(AbstractUser):
"""When a user first arrives on the site, we need to retrieve any domain """When a user first arrives on the site, we need to retrieve any domain
invitations that match their email address.""" invitations that match their email address."""
for invitation in DomainInvitation.objects.filter( for invitation in DomainInvitation.objects.filter(
email=self.email, status=DomainInvitation.DomainInvitationStatus.INVITED email__iexact=self.email, status=DomainInvitation.DomainInvitationStatus.INVITED
): ):
try: try:
invitation.retrieve() invitation.retrieve()

View file

@ -654,3 +654,17 @@ class TestUser(TestCase):
"""A new user who's neither transitioned nor invited should """A new user who's neither transitioned nor invited should
return True when tested with class method needs_identity_verification""" return True when tested with class method needs_identity_verification"""
self.assertTrue(User.needs_identity_verification(self.user.email, self.user.username)) self.assertTrue(User.needs_identity_verification(self.user.email, self.user.username))
def test_check_domain_invitations_on_login_caps_email(self):
"""A DomainInvitation with an email address with capital letters should match
a User record whose email address is not in caps"""
# create DomainInvitation with CAPS email that matches User email
# on a case-insensitive match
CAPS_EMAIL = "MAYOR@igorville.gov"
# mock the domain invitation save routine
with patch("registrar.models.DomainInvitation.save") as save_mock:
DomainInvitation.objects.get_or_create(email=CAPS_EMAIL, domain=self.domain)
self.user.check_domain_invitations_on_login()
# if check_domain_invitations_on_login properly matches exactly one
# Domain Invitation, then save routine should be called exactly once
save_mock.assert_called_once

View file

@ -1372,6 +1372,32 @@ class TestDomainManagers(TestDomainOverview):
self.assertContains(success_page, "Cancel") # link to cancel invitation self.assertContains(success_page, "Cancel") # link to cancel invitation
self.assertTrue(DomainInvitation.objects.filter(email=EMAIL).exists()) self.assertTrue(DomainInvitation.objects.filter(email=EMAIL).exists())
@boto3_mocking.patching
def test_domain_invitation_created_for_caps_email(self):
"""Add user on a nonexistent email with CAPS creates an invitation to lowercase email.
Adding a non-existent user sends an email as a side-effect, so mock
out the boto3 SES email sending here.
"""
# make sure there is no user with this email
EMAIL = "mayor@igorville.gov"
CAPS_EMAIL = "MAYOR@igorville.gov"
User.objects.filter(email=EMAIL).delete()
self.domain_information, _ = DomainInformation.objects.get_or_create(creator=self.user, domain=self.domain)
add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id}))
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
add_page.form["email"] = CAPS_EMAIL
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
success_result = add_page.form.submit()
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
success_page = success_result.follow()
self.assertContains(success_page, EMAIL)
self.assertContains(success_page, "Cancel") # link to cancel invitation
self.assertTrue(DomainInvitation.objects.filter(email=EMAIL).exists())
@boto3_mocking.patching @boto3_mocking.patching
def test_domain_invitation_email_sent(self): def test_domain_invitation_email_sent(self):
"""Inviting a non-existent user sends them an email.""" """Inviting a non-existent user sends them an email."""