From 098c5a3f0223ea3d97b7c95404ad8447977ca06c Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Sun, 21 Jul 2024 23:40:49 +0200 Subject: [PATCH 1/2] fix: Send create user email for password resets where we have an email and person, but no user account This fixes https://github.com/ietf-tools/datatracker/issues/6458 --- ietf/ietfauth/tests.py | 18 ++++++++++++++++++ ietf/ietfauth/views.py | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 6a85c6eb13..86f2051581 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -527,6 +527,24 @@ def test_reset_password_without_username(self): self.assertIn(secondary_address, to) self.assertNotIn(inactive_secondary_address, to) + def test_reset_password_without_user(self): + """Reset password using email address for person without a user account""" + url = urlreverse('ietf.ietfauth.views.password_reset') + email = EmailFactory() + person = email.person + # Remove the user object from the person to get a Email/Person without User: + person.user = None + person.save() + # Remove the remaining User record, since reset_password looks for that by username: + User.objects.filter(username__iexact=email.address).delete() + empty_outbox() + r = self.client.post(url, { 'username': email.address }) + self.assertEqual(len(outbox), 1) + lastReceivedEmail = outbox[-1] + self.assertIn(email.address, lastReceivedEmail.get('To')) + self.assertTrue(lastReceivedEmail.get('Subject').startswith('Confirm registration at')) + self.assertContains(r, 'We have sent you an email with instructions', status_code=200) + def test_review_overview(self): review_req = ReviewRequestFactory() assignment = ReviewAssignmentFactory(review_request=review_req,reviewer=EmailFactory(person__user__username='reviewer')) diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index 61c7b929b1..d40118834b 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -491,8 +491,11 @@ def password_reset(request): if not user: # try to find user ID from the email address email = Email.objects.filter(address=submitted_username).first() - if email and email.person and email.person.user: - user = email.person.user + if email and email.person: + if email.person.user: + user = email.person.user + else: + send_account_creation_email(request, email.email_address()) if user and user.person.email_set.filter(active=True).exists(): data = { From 08b2290ca9490312e997c802205c06e416ad3dd2 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Mon, 5 Aug 2024 12:45:40 -0500 Subject: [PATCH 2/2] fix: create User straight away and use nomral password reset --- ietf/ietfauth/tests.py | 4 ++-- ietf/ietfauth/views.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 86f2051581..722c1e8b6f 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -542,8 +542,8 @@ def test_reset_password_without_user(self): self.assertEqual(len(outbox), 1) lastReceivedEmail = outbox[-1] self.assertIn(email.address, lastReceivedEmail.get('To')) - self.assertTrue(lastReceivedEmail.get('Subject').startswith('Confirm registration at')) - self.assertContains(r, 'We have sent you an email with instructions', status_code=200) + self.assertTrue(lastReceivedEmail.get('Subject').startswith("Confirm password reset")) + self.assertContains(r, "Your password reset request has been successfully received", status_code=200) def test_review_overview(self): review_req = ReviewRequestFactory() diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index d40118834b..32bb5c92be 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -495,8 +495,15 @@ def password_reset(request): if email.person.user: user = email.person.user else: - send_account_creation_email(request, email.email_address()) - + # Create a User record with this (conditioned by way of Email) username + # Don't bother setting the name or email fields on User - rely on the + # Person pointer. + user = User.objects.create( + username=email.address.lower(), + is_active=True, + ) + email.person.user = user + email.person.save() if user and user.person.email_set.filter(active=True).exists(): data = { 'username': user.username,