handling of failed email sends to domain managers

This commit is contained in:
David Kennedy 2025-01-29 15:02:46 -05:00
parent bc7bc4d6e1
commit 6634e9bad8
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
5 changed files with 36 additions and 22 deletions

View file

@ -1410,7 +1410,7 @@ class BaseInvitationAdmin(ListHeaderAdmin):
# store current messages from request so that they are preserved throughout the method
storage = get_messages(request)
# Check if there are any error or warning messages in the `messages` framework
has_errors = any(message.level_tag in ["error", "warning"] for message in storage)
has_errors = any(message.level_tag in ["error"] for message in storage)
if has_errors:
# Re-render the change form if there are errors or warnings
@ -1552,13 +1552,14 @@ class DomainInvitationAdmin(BaseInvitationAdmin):
portfolio_invitation.save()
messages.success(request, f"{requested_email} has been invited to the organization: {domain_org}")
send_domain_invitation_email(
if not send_domain_invitation_email(
email=requested_email,
requestor=requestor,
domains=domain,
is_member_of_different_org=member_of_a_different_org,
requested_user=requested_user,
)
):
messages.warning(request, "Could not send email confirmation to existing domain managers.")
if requested_user is not None:
# Domain Invitation creation for an existing User
obj.retrieve()

View file

@ -27,6 +27,9 @@ def send_domain_invitation_email(
is_member_of_different_org (bool): if an email belongs to a different org
requested_user (User | None): The recipient if the email belongs to a user in the registrar
Returns:
Boolean indicating if all messages were sent successfully.
Raises:
MissingEmailError: If the requestor has no email associated with their account.
AlreadyDomainManagerError: If the email corresponds to an existing domain manager.
@ -41,22 +44,28 @@ def send_domain_invitation_email(
send_invitation_email(email, requestor_email, domains, requested_user)
all_manager_emails_sent = True
# send emails to domain managers
for domain in domains:
send_emails_to_domain_managers(
if not send_emails_to_domain_managers(
email=email,
requestor_email=requestor_email,
domain=domain,
requested_user=requested_user,
)
):
all_manager_emails_sent = False
return all_manager_emails_sent
def send_emails_to_domain_managers(email: str, requestor_email, domain: Domain, requested_user=None):
"""
Notifies all domain managers of the provided domain of a change
Raises:
EmailSendingError
Returns:
Boolean indicating if all messages were sent successfully.
"""
all_emails_sent = True
# Get each domain manager from list
user_domain_roles = UserDomainRole.objects.filter(domain=domain)
for user_domain_role in user_domain_roles:
@ -76,9 +85,9 @@ def send_emails_to_domain_managers(email: str, requestor_email, domain: Domain,
},
)
except EmailSendingError as err:
raise EmailSendingError(
f"Could not send email manager notification to {user.email} for domain: {domain.name}"
) from err
logger.warning(f"Could not send email manager notification to {user.email} for domain: {domain.name}")
all_emails_sent = False
return all_emails_sent
def normalize_domains(domains: Domain | list[Domain]) -> list[Domain]:

View file

@ -1244,24 +1244,26 @@ class DomainAddUserView(DomainFormBaseView):
def _handle_new_user_invitation(self, email, requestor, member_of_different_org):
"""Handle invitation for a new user who does not exist in the system."""
send_domain_invitation_email(
if not send_domain_invitation_email(
email=email,
requestor=requestor,
domains=self.object,
is_member_of_different_org=member_of_different_org,
)
):
messages.warning(self.request, "Could not send email confirmation to existing domain managers.")
DomainInvitation.objects.get_or_create(email=email, domain=self.object)
messages.success(self.request, f"{email} has been invited to the domain: {self.object}")
def _handle_existing_user(self, email, requestor, requested_user, member_of_different_org):
"""Handle adding an existing user to the domain."""
send_domain_invitation_email(
if not send_domain_invitation_email(
email=email,
requestor=requestor,
domains=self.object,
is_member_of_different_org=member_of_different_org,
requested_user=requested_user,
)
):
messages.warning(self.request, "Could not send email confirmation to existing domain managers.")
UserDomainRole.objects.create(
user=requested_user,
domain=self.object,

View file

@ -299,13 +299,14 @@ class PortfolioMemberDomainsEditView(PortfolioMemberDomainsEditPermissionView, V
# get added_domains from ids to pass to send email method and bulk create
added_domains = Domain.objects.filter(id__in=added_domain_ids)
member_of_a_different_org, _ = get_org_membership(portfolio, member.email, member)
send_domain_invitation_email(
if not send_domain_invitation_email(
email=member.email,
requestor=requestor,
domains=added_domains,
is_member_of_different_org=member_of_a_different_org,
requested_user=member,
)
):
messages.warning(self.request, "Could not send email confirmation to existing domain managers.")
# Bulk create UserDomainRole instances for added domains
UserDomainRole.objects.bulk_create(
[
@ -517,12 +518,13 @@ class PortfolioInvitedMemberDomainsEditView(PortfolioMemberDomainsEditPermission
# get added_domains from ids to pass to send email method and bulk create
added_domains = Domain.objects.filter(id__in=added_domain_ids)
member_of_a_different_org, _ = get_org_membership(portfolio, email, None)
send_domain_invitation_email(
if not send_domain_invitation_email(
email=email,
requestor=requestor,
domains=added_domains,
is_member_of_different_org=member_of_a_different_org,
)
):
messages.warning(self.request, "Could not send email confirmation to existing domain managers.")
# Update existing invitations from CANCELED to INVITED
existing_invitations = DomainInvitation.objects.filter(domain__in=added_domains, email=email)

View file

@ -70,11 +70,11 @@ def handle_invitation_exceptions(request, exception, email):
messages.error(request, str(exception))
logger.warning(str(exception), exc_info=True)
elif isinstance(exception, AlreadyDomainManagerError):
messages.warning(request, str(exception))
messages.error(request, str(exception))
elif isinstance(exception, AlreadyDomainInvitedError):
messages.warning(request, str(exception))
messages.error(request, str(exception))
elif isinstance(exception, IntegrityError):
messages.warning(request, f"{email} is already a manager for this domain")
messages.error(request, f"{email} is already a manager for this domain")
else:
logger.warning("Could not send email invitation (Other Exception)", exc_info=True)
messages.warning(request, "Could not send email invitation.")
messages.error(request, "Could not send email invitation.")