diff --git a/src/registrar/admin.py b/src/registrar/admin.py index e1bf25449..a47617c28 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -10,6 +10,7 @@ from django.http import HttpResponseRedirect from django.shortcuts import redirect from django_fsm import get_available_FIELD_transitions, FSMField from registrar.models.domain_information import DomainInformation +from registrar.models.user_portfolio_permission import UserPortfolioPermission from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices from waffle.decorators import flag_is_active from django.contrib import admin, messages @@ -3008,6 +3009,28 @@ class PortfolioAdmin(ListHeaderAdmin): "creator", ] + def get_admin_users(self, obj): + # Filter UserPortfolioPermission objects related to the portfolio + admin_permissions = UserPortfolioPermission.objects.filter( + portfolio=obj, roles__contains=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN] + ) + + # Get the user objects associated with these permissions + admin_users = User.objects.filter(portfolio_permissions__in=admin_permissions) + + return admin_users + + def get_non_admin_users(self, obj): + # Filter UserPortfolioPermission objects related to the portfolio that do NOT have the "Admin" role + non_admin_permissions = UserPortfolioPermission.objects.filter(portfolio=obj).exclude( + roles__contains=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN] + ) + + # Get the user objects associated with these permissions + non_admin_users = User.objects.filter(portfolio_permissions__in=non_admin_permissions) + + return non_admin_users + def display_admins(self, obj): """Get joined users who are Admin, unpack and return an HTML block. @@ -3016,7 +3039,7 @@ class PortfolioAdmin(ListHeaderAdmin): data would display in a custom change form without extensive template customization. Will be used in the field_readonly block""" - admins = [user for user in obj.user.all() if "Admin" in user.portfolio_role_summary] + admins = self.get_admin_users(obj) if not admins: return format_html("

No admins found.

") @@ -3030,13 +3053,13 @@ class PortfolioAdmin(ListHeaderAdmin): admin_details += "
" admin_details += f"{portfolio_admin.phone}" @@ -3053,7 +3076,7 @@ class PortfolioAdmin(ListHeaderAdmin): data would display in a custom change form without extensive template customization. Will be used in the after_help_text block.""" - members = [user for user in obj.user.all() if "Admin" not in user.portfolio_role_summary] + members = self.get_non_admin_users(obj) if not members: return "" @@ -3073,7 +3096,7 @@ class PortfolioAdmin(ListHeaderAdmin): member_details += f"{member.email}" member_details += f"{member.phone}" member_details += "" - for role in member.portfolio_role_summary: + for role in member.portfolio_role_summary(obj): member_details += f"{role} " member_details += "" member_details += "" @@ -3083,7 +3106,7 @@ class PortfolioAdmin(ListHeaderAdmin): def display_members_summary(self, obj): """Will be passed as context and used in the field_readonly block.""" - members = [user for user in obj.user.all() if "Admin" not in user.portfolio_role_summary] + members = self.get_non_admin_users(obj) if not members: return {} diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 2c17b7b27..8d91c2a8c 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -245,39 +245,39 @@ class User(AbstractUser): return permission.portfolio return None - def has_edit_requests(self): - return self._has_portfolio_permission(UserPortfolioPermissionChoices.EDIT_REQUESTS) + def has_edit_requests(self, portfolio): + return self._has_portfolio_permission(portfolio, UserPortfolioPermissionChoices.EDIT_REQUESTS) - @property - def portfolio_role_summary(self): + def portfolio_role_summary(self, portfolio): """Returns a list of roles based on the user's permissions.""" roles = [] # Define the conditions and their corresponding roles conditions_roles = [ - (self.has_edit_suborganization(), ["Admin"]), + (self.has_edit_suborganization(portfolio), ["Admin"]), ( - self.has_view_all_domains_permission() - and self.has_domain_requests_portfolio_permission() - and self.has_edit_requests(), + self.has_view_all_domains_permission(portfolio) + and self.has_domain_requests_portfolio_permission(portfolio) + and self.has_edit_requests(portfolio), ["View-only admin", "Domain requestor"], ), ( - self.has_view_all_domains_permission() and self.has_domain_requests_portfolio_permission(), + self.has_view_all_domains_permission(portfolio) + and self.has_domain_requests_portfolio_permission(portfolio), ["View-only admin"], ), ( - self.has_base_portfolio_permission() - and self.has_edit_requests() - and self.has_domains_portfolio_permission(), + self.has_base_portfolio_permission(portfolio) + and self.has_edit_requests(portfolio) + and self.has_domains_portfolio_permission(portfolio), ["Domain requestor", "Domain manager"], ), - (self.has_base_portfolio_permission() and self.has_edit_requests(), ["Domain requestor"]), + (self.has_base_portfolio_permission(portfolio) and self.has_edit_requests(portfolio), ["Domain requestor"]), ( - self.has_base_portfolio_permission() and self.has_domains_portfolio_permission(), + self.has_base_portfolio_permission(portfolio) and self.has_domains_portfolio_permission(portfolio), ["Domain manager"], ), - (self.has_base_portfolio_permission(), ["Member"]), + (self.has_base_portfolio_permission(portfolio), ["Member"]), ] # Evaluate conditions and add roles diff --git a/src/registrar/templates/admin/input_with_clipboard.html b/src/registrar/templates/admin/input_with_clipboard.html index ea2fbce33..5ad2b27f7 100644 --- a/src/registrar/templates/admin/input_with_clipboard.html +++ b/src/registrar/templates/admin/input_with_clipboard.html @@ -17,7 +17,7 @@ Template for an input field with a clipboard > - Copy + Copy @@ -25,7 +25,7 @@ Template for an input field with a clipboard {% endif %} \ No newline at end of file diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 02cd6e0f6..93e611c1a 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -45,6 +45,7 @@ from registrar.models import ( from registrar.models.portfolio_invitation import PortfolioInvitation from registrar.models.senior_official import SeniorOfficial from registrar.models.user_domain_role import UserDomainRole +from registrar.models.user_portfolio_permission import UserPortfolioPermission from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices from registrar.models.verified_by_staff import VerifiedByStaff from .common import ( @@ -2129,8 +2130,10 @@ class TestPortfolioAdmin(TestCase): last_name="Meoward", title="Captain", email="meaoward@gov.gov", - portfolio=self.portfolio, - portfolio_roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN], + ) + + UserPortfolioPermission.objects.all().create( + user=admin_user_1, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN] ) admin_user_2 = User.objects.create( @@ -2139,8 +2142,10 @@ class TestPortfolioAdmin(TestCase): last_name="Poopy", title="Major", email="poopy@gov.gov", - portfolio=self.portfolio, - portfolio_roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN], + ) + + UserPortfolioPermission.objects.all().create( + user=admin_user_2, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN] ) admin_user_3 = User.objects.create( @@ -2149,8 +2154,10 @@ class TestPortfolioAdmin(TestCase): last_name="Max", title="Road warrior", email="madmax@gov.gov", - portfolio=self.portfolio, - portfolio_roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER], + ) + + UserPortfolioPermission.objects.all().create( + user=admin_user_3, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER] ) admin_user_4 = User.objects.create( @@ -2159,8 +2166,12 @@ class TestPortfolioAdmin(TestCase): last_name="Smith", title="Program", email="thematrix@gov.gov", + ) + + UserPortfolioPermission.objects.all().create( + user=admin_user_4, portfolio=self.portfolio, - portfolio_additional_permissions=[ + additional_permissions=[ UserPortfolioPermissionChoices.VIEW_PORTFOLIO, UserPortfolioPermissionChoices.EDIT_REQUESTS, ],