mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-14 08:37:03 +02:00
Revise for multiple portfolios
This commit is contained in:
parent
fc2f4f08cc
commit
2af57c8aa8
4 changed files with 65 additions and 31 deletions
|
@ -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("<p>No admins found.</p>")
|
||||
|
||||
|
@ -3030,13 +3053,13 @@ class PortfolioAdmin(ListHeaderAdmin):
|
|||
admin_details += "<div class='admin-icon-group admin-icon-group__clipboard-link'>"
|
||||
admin_details += f"<input aria-hidden='true' class='display-none' value='{portfolio_admin.email}'>"
|
||||
admin_details += (
|
||||
"<button class='usa-button usa-button--unstyled padding-right-1 usa-button--icon"
|
||||
"<button class='usa-button usa-button--unstyled padding-right-1 usa-button--icon padding-left-05"
|
||||
+ "button--clipboard copy-to-clipboard text-no-underline' type='button'>"
|
||||
)
|
||||
admin_details += "<svg class='usa-icon'>"
|
||||
admin_details += "<use aria-hidden='true' xlink:href='/public/img/sprite.svg#content_copy'></use>"
|
||||
admin_details += "</svg>"
|
||||
admin_details += "<span class='padding-left-05'>Copy</span>"
|
||||
admin_details += "Copy"
|
||||
admin_details += "</button>"
|
||||
admin_details += "</div><br>"
|
||||
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"<td>{member.email}</td>"
|
||||
member_details += f"<td>{member.phone}</td>"
|
||||
member_details += "<td>"
|
||||
for role in member.portfolio_role_summary:
|
||||
for role in member.portfolio_role_summary(obj):
|
||||
member_details += f"<span class='usa-tag'>{role}</span> "
|
||||
member_details += "</td></tr>"
|
||||
member_details += "</tbody></table>"
|
||||
|
@ -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 {}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,7 +17,7 @@ Template for an input field with a clipboard
|
|||
>
|
||||
<use aria-hidden="true" xlink:href="{%static 'img/sprite.svg'%}#content_copy"></use>
|
||||
</svg>
|
||||
<span>Copy</span>
|
||||
Copy
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -25,7 +25,7 @@ Template for an input field with a clipboard
|
|||
<div class="admin-icon-group admin-icon-group__clipboard-link">
|
||||
<input aria-hidden="true" class="display-none" value="{{ field.email }}" />
|
||||
<button
|
||||
class="usa-button usa-button--unstyled padding-right-1 usa-button--icon button--clipboard copy-to-clipboard text-no-underline"
|
||||
class="usa-button usa-button--unstyled padding-right-1 usa-button--icon button--clipboard copy-to-clipboard text-no-underline padding-left-05"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
|
@ -33,7 +33,7 @@ Template for an input field with a clipboard
|
|||
>
|
||||
<use aria-hidden="true" xlink:href="{%static 'img/sprite.svg'%}#content_copy"></use>
|
||||
</svg>
|
||||
<span class="padding-left-05">Copy</span>
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
|
@ -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,
|
||||
],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue