This commit is contained in:
zandercymatics 2025-03-12 10:29:38 -06:00
parent bde4f1fec5
commit 585569a006
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
2 changed files with 57 additions and 13 deletions

View file

@ -22,6 +22,7 @@ from registrar.models.utility.portfolio_helper import (
get_domains_display, get_domains_display,
get_members_description_display, get_members_description_display,
get_members_display, get_members_display,
get_portfolio_invitation_associations,
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -459,6 +460,13 @@ class PortfolioNewMemberForm(BasePortfolioMemberForm):
if hasattr(e, "code"): if hasattr(e, "code"):
field = "email" if "email" in self.fields else None field = "email" if "email" in self.fields else None
if e.code == "has_existing_permissions": if e.code == "has_existing_permissions":
existing_permissions, existing_invitations = (
get_portfolio_invitation_associations(self.instance)
)
same_portfolio_for_permissions = existing_permissions.exclude(portfolio=self.instance.portfolio)
same_portfolio_for_invitations = existing_invitations.exclude(portfolio=self.instance.portfolio)
if same_portfolio_for_permissions.exists() or same_portfolio_for_invitations.exists():
self.add_error(field, f"{self.instance.email} is already a member of another .gov organization.") self.add_error(field, f"{self.instance.email} is already a member of another .gov organization.")
override_error = True override_error = True
elif e.code == "has_existing_invitations": elif e.code == "has_existing_invitations":

View file

@ -286,8 +286,8 @@ def validate_user_portfolio_permission(user_portfolio_permission):
# == Validate the multiple_porfolios flag. == # # == Validate the multiple_porfolios flag. == #
if not flag_is_active_for_user(user_portfolio_permission.user, "multiple_portfolios"): if not flag_is_active_for_user(user_portfolio_permission.user, "multiple_portfolios"):
existing_permissions = UserPortfolioPermission.objects.exclude(id=user_portfolio_permission.id).filter( existing_permissions, existing_invitations = (
user=user_portfolio_permission.user get_user_portfolio_permission_associations(user_portfolio_permission)
) )
if existing_permissions.exists(): if existing_permissions.exists():
raise ValidationError( raise ValidationError(
@ -296,10 +296,6 @@ def validate_user_portfolio_permission(user_portfolio_permission):
code="has_existing_permissions", code="has_existing_permissions",
) )
existing_invitations = PortfolioInvitation.objects.filter(email=user_portfolio_permission.user.email).exclude(
Q(portfolio=user_portfolio_permission.portfolio)
| Q(status=PortfolioInvitation.PortfolioInvitationStatus.RETRIEVED)
)
if existing_invitations.exists(): if existing_invitations.exists():
raise ValidationError( raise ValidationError(
"This user is already assigned to a portfolio invitation. " "This user is already assigned to a portfolio invitation. "
@ -307,6 +303,29 @@ def validate_user_portfolio_permission(user_portfolio_permission):
code="has_existing_invitations", code="has_existing_invitations",
) )
def get_user_portfolio_permission_associations(user_portfolio_permission):
"""
Retrieves the associations for a user portfolio invitation.
Returns:
A tuple:
(existing_permissions, existing_invitations)
where:
- existing_permissions: UserPortfolioPermission objects excluding the current permission.
- existing_invitations: PortfolioInvitation objects for the user email excluding
the current invitation and those with status RETRIEVED.
"""
PortfolioInvitation = apps.get_model("registrar.PortfolioInvitation")
UserPortfolioPermission = apps.get_model("registrar.UserPortfolioPermission")
existing_permissions = UserPortfolioPermission.objects.exclude(id=user_portfolio_permission.id).filter(
user=user_portfolio_permission.user
)
existing_invitations = PortfolioInvitation.objects.filter(email__iexact=user_portfolio_permission.user.email).exclude(
Q(portfolio=user_portfolio_permission.portfolio)
| Q(status=PortfolioInvitation.PortfolioInvitationStatus.RETRIEVED)
)
return (existing_permissions, existing_invitations)
def validate_portfolio_invitation(portfolio_invitation): def validate_portfolio_invitation(portfolio_invitation):
""" """
@ -351,17 +370,14 @@ def validate_portfolio_invitation(portfolio_invitation):
) )
# == Validate the multiple_porfolios flag. == # # == Validate the multiple_porfolios flag. == #
user = User.objects.filter(email=portfolio_invitation.email).first() user = User.objects.filter(email__iexact=portfolio_invitation.email).first()
# If user returns None, then we check for global assignment of multiple_portfolios. # If user returns None, then we check for global assignment of multiple_portfolios.
# Otherwise we just check on the user. # Otherwise we just check on the user.
if not flag_is_active_for_user(user, "multiple_portfolios"): if not flag_is_active_for_user(user, "multiple_portfolios"):
existing_permissions = UserPortfolioPermission.objects.filter(user=user) existing_permissions, existing_invitations = (
get_portfolio_invitation_associations(portfolio_invitation)
existing_invitations = PortfolioInvitation.objects.filter(email=portfolio_invitation.email).exclude(
Q(id=portfolio_invitation.id) | Q(status=PortfolioInvitation.PortfolioInvitationStatus.RETRIEVED)
) )
if existing_permissions.exists(): if existing_permissions.exists():
raise ValidationError( raise ValidationError(
"This user is already assigned to a portfolio. " "This user is already assigned to a portfolio. "
@ -376,6 +392,26 @@ def validate_portfolio_invitation(portfolio_invitation):
code="has_existing_invitations", code="has_existing_invitations",
) )
def get_portfolio_invitation_associations(portfolio_invitation):
"""
Retrieves the associations for a portfolio invitation.
Returns:
A tuple:
(existing_permissions, existing_invitations)
where:
- existing_permissions: UserPortfolioPermission objects matching the email.
- existing_invitations: PortfolioInvitation objects for the email excluding
the current invitation and those with status RETRIEVED.
"""
PortfolioInvitation = apps.get_model("registrar.PortfolioInvitation")
UserPortfolioPermission = apps.get_model("registrar.UserPortfolioPermission")
existing_permissions = UserPortfolioPermission.objects.filter(user__email__iexact=portfolio_invitation.email)
existing_invitations = PortfolioInvitation.objects.filter(email__iexact=portfolio_invitation.email).exclude(
Q(id=portfolio_invitation.id) | Q(status=PortfolioInvitation.PortfolioInvitationStatus.RETRIEVED)
)
return (existing_permissions, existing_invitations)
def cleanup_after_portfolio_member_deletion(portfolio, email, user=None): def cleanup_after_portfolio_member_deletion(portfolio, email, user=None):
""" """