Add error code for outside org members being added

This commit is contained in:
Erin Song 2024-09-26 14:45:10 -07:00
parent 8b61eb1275
commit b0fe698af2
No known key found for this signature in database
2 changed files with 41 additions and 33 deletions

View file

@ -23,6 +23,14 @@ class InvalidDomainError(ValueError):
pass pass
class OutsideOrgMemberError(ValueError):
"""
Error raised when an org member tries adding a user from a different .gov org.
To be deleted when users can be members of multiple orgs.
"""
pass
class ActionNotAllowed(Exception): class ActionNotAllowed(Exception):
"""User accessed an action that is not """User accessed an action that is not
allowed by the current state""" allowed by the current state"""

View file

@ -35,6 +35,7 @@ from registrar.utility.errors import (
NameserverErrorCodes as nsErrorCodes, NameserverErrorCodes as nsErrorCodes,
DsDataError, DsDataError,
DsDataErrorCodes, DsDataErrorCodes,
OutsideOrgMemberError,
SecurityEmailError, SecurityEmailError,
SecurityEmailErrorCodes, SecurityEmailErrorCodes,
) )
@ -781,12 +782,15 @@ class DomainAddUserView(DomainFormBaseView):
"""Get an absolute URL for this domain.""" """Get an absolute URL for this domain."""
return self.request.build_absolute_uri(reverse("domain", kwargs={"pk": self.object.id})) return self.request.build_absolute_uri(reverse("domain", kwargs={"pk": self.object.id}))
def _is_member_of_different_org(self, email, org): def _is_member_of_different_org(self, email, requested_user, org):
"""Verifies if an email belongs to a different organization as a member or invited member.""" """Verifies if an email belongs to a different organization as a member or invited member."""
# Check if user is a member of a different organization # Check if user is a already member of a different organization than the given org
existing_org_permission = UserPortfolioPermission.objects.get(email=email) existing_org_permission = UserPortfolioPermission.objects.filter(user=requested_user).first()
print("Existing org permission: ", existing_org_permission) existing_org_invitation = PortfolioInvitation.objects.filter(email=email).first()
return True
return (existing_org_permission and existing_org_permission.portfolio != org) or (
existing_org_invitation and existing_org_invitation.portfolio != org
)
def _send_domain_invitation_email(self, email: str, requestor: User, requested_user=None, add_success=True): def _send_domain_invitation_email(self, email: str, requestor: User, requested_user=None, add_success=True):
"""Performs the sending of the domain invitation email, """Performs the sending of the domain invitation email,
@ -814,24 +818,16 @@ class DomainAddUserView(DomainFormBaseView):
return None return None
# Check is user is a member or invited member of a different org from this domain's org # Check is user is a member or invited member of a different org from this domain's org
print("org feature flag is active: ", flag_is_active_for_user(requestor, "organization_feature"))
if flag_is_active_for_user(requestor, "organization_feature"): if flag_is_active_for_user(requestor, "organization_feature"):
# Check if invited user is a member from a different org from this domain's org # Check if invited user is a member from a different org from this domain's org
existing_org_permission = UserPortfolioPermission.objects.filter(user=requested_user).first()
print("Existing org permission for requested email: ", existing_org_permission)
existing_org_invitation = PortfolioInvitation.objects.filter(email=email).first()
requestor_org = UserPortfolioPermission.objects.get(user=requestor).portfolio requestor_org = UserPortfolioPermission.objects.get(user=requestor).portfolio
print("Requestor org: ", requestor_org) if self._is_member_of_different_org(email, requested_user, requestor_org):
if (existing_org_permission and existing_org_permission.portfolio != requestor_org) or (
existing_org_invitation and existing_org_invitation.portfolio != requestor_org
):
add_success = False add_success = False
messages.error( messages.error(
self.request, self.request,
f"That email is already a member of another .gov organization.", "That email is already a member of another .gov organization.",
) )
raise Exception raise OutsideOrgMemberError
# Check to see if an invite has already been sent # Check to see if an invite has already been sent
try: try:
@ -847,10 +843,7 @@ class DomainAddUserView(DomainFormBaseView):
add_success = False add_success = False
# else if it has been sent but not accepted # else if it has been sent but not accepted
messages.warning(self.request, f"{email} has already been invited to this domain") messages.warning(self.request, f"{email} has already been invited to this domain")
except Exception:
logger.error("An error occured")
try:
send_templated_email( send_templated_email(
"emails/domain_invitation.txt", "emails/domain_invitation.txt",
"emails/domain_invitation_subject.txt", "emails/domain_invitation_subject.txt",
@ -861,6 +854,11 @@ class DomainAddUserView(DomainFormBaseView):
"requestor_email": requestor_email, "requestor_email": requestor_email,
}, },
) )
if add_success:
messages.success(self.request, f"{email} has been invited to this domain.")
except Exception:
logger.error("An error occured")
except EmailSendingError as exc: except EmailSendingError as exc:
logger.warn( logger.warn(
"Could not sent email invitation to %s for domain %s", "Could not sent email invitation to %s for domain %s",
@ -869,9 +867,6 @@ class DomainAddUserView(DomainFormBaseView):
exc_info=True, exc_info=True,
) )
raise EmailSendingError("Could not send email invitation.") from exc raise EmailSendingError("Could not send email invitation.") from exc
else:
if add_success:
messages.success(self.request, f"{email} has been invited to this domain.")
def _make_invitation(self, email_address: str, requestor: User): def _make_invitation(self, email_address: str, requestor: User):
"""Make a Domain invitation for this email and redirect with a message.""" """Make a Domain invitation for this email and redirect with a message."""
@ -901,6 +896,14 @@ class DomainAddUserView(DomainFormBaseView):
self._send_domain_invitation_email( self._send_domain_invitation_email(
requested_email, requestor, requested_user=requested_user, add_success=False requested_email, requestor, requested_user=requested_user, add_success=False
) )
UserDomainRole.objects.create(
user=requested_user,
domain=self.object,
role=UserDomainRole.Roles.MANAGER,
)
messages.success(self.request, f"Added user {requested_email}.")
except EmailSendingError: except EmailSendingError:
logger.warn( logger.warn(
"Could not send email invitation (EmailSendingError)", "Could not send email invitation (EmailSendingError)",
@ -908,6 +911,12 @@ class DomainAddUserView(DomainFormBaseView):
exc_info=True, exc_info=True,
) )
messages.warning(self.request, "Could not send email invitation.") messages.warning(self.request, "Could not send email invitation.")
except OutsideOrgMemberError:
logger.warn(
"Could not send email invitation to a user in a different org.",
self.object,
exc_info=True,
)
except Exception: except Exception:
logger.warn( logger.warn(
"Could not send email invitation (Other Exception)", "Could not send email invitation (Other Exception)",
@ -915,17 +924,8 @@ class DomainAddUserView(DomainFormBaseView):
exc_info=True, exc_info=True,
) )
messages.warning(self.request, "Could not send email invitation.") messages.warning(self.request, "Could not send email invitation.")
else:
try:
UserDomainRole.objects.create(
user=requested_user,
domain=self.object,
role=UserDomainRole.Roles.MANAGER,
)
except IntegrityError: except IntegrityError:
messages.warning(self.request, f"{requested_email} is already a manager for this domain") messages.warning(self.request, f"{requested_email} is already a manager for this domain")
else:
messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url()) return redirect(self.get_success_url())