fix: Handle email sending failures gracefully

Adds exception handling for SMTPRecipientsRefused to prevent
unhandled exceptions when email delivery fails. Provides
user feedback on email verification failure and removes
registration record if the initial verification email fails.

Improves user experience by allowing system to continue even
if an email address is invalid or blocked.
This commit is contained in:
Kumi 2024-11-20 10:15:43 +01:00
parent 3a032b02f4
commit 9a94f4b905
Signed by: kumi
GPG key ID: ECBCC9082395383F
2 changed files with 38 additions and 21 deletions

View file

@ -7,6 +7,8 @@ from .models import UserRegistration
import requests
from smtplib import SMTPRecipientsRefused
@receiver(post_save, sender=UserRegistration)
def handle_status_change(sender, instance, created, **kwargs):
@ -35,21 +37,17 @@ def handle_status_change(sender, instance, created, **kwargs):
headers={"Authorization": f"Bearer {settings.SYNAPSE_ADMIN_TOKEN}"},
)
try:
send_mail(
"Registration Approved",
f"Congratulations, {instance.username}! Your registration at {settings.MATRIX_DOMAIN} has been approved.",
settings.DEFAULT_FROM_EMAIL,
[instance.email],
)
except SMTPRecipientsRefused:
pass
elif status == UserRegistration.STATUS_DENIED:
send_mail(
"Registration Denied",
f"Sorry, your registration request at {settings.MATRIX_DOMAIN} has been denied.",
settings.DEFAULT_FROM_EMAIL,
[instance.email],
)
response = requests.put(
f"{settings.SYNAPSE_SERVER}/_synapse/admin/v2/users/@{instance.username}:{settings.MATRIX_DOMAIN}",
json={"deactivated": True},
@ -63,3 +61,13 @@ def handle_status_change(sender, instance, created, **kwargs):
settings.DEFAULT_FROM_EMAIL,
[settings.ADMIN_EMAIL],
)
try:
send_mail(
"Registration Denied",
f"Sorry, your registration request at {settings.MATRIX_DOMAIN} has been denied.",
settings.DEFAULT_FROM_EMAIL,
[instance.email],
)
except SMTPRecipientsRefused:
pass

View file

@ -11,6 +11,7 @@ import requests
from secrets import token_urlsafe
from datetime import datetime, timedelta
from smtplib import SMTPRecipientsRefused
class LandingPageView(TemplateView):
@ -76,15 +77,18 @@ class EmailInputView(FormView):
token = token_urlsafe(32)
UserRegistration.objects.create(
registration = UserRegistration.objects.create(
username=self.request.session["username"],
email=email,
token=token,
ip_address=ip_address,
)
verification_link = self.request.build_absolute_uri(
reverse_lazy("verify_email", args=[token])
)
try:
send_mail(
"Verify your email",
f"Click the link to verify your email: {verification_link}",
@ -93,6 +97,11 @@ class EmailInputView(FormView):
)
return render(self.request, "registration/email_sent.html")
except SMTPRecipientsRefused:
form.add_error("email", "Your email address is invalid, not accepting mail, or blocked by our mail server.")
registration.delete()
return self.form_invalid(form)
class VerifyEmailView(View):
def get(self, request, token):