mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-26 04:28:39 +02:00
initial working code
This commit is contained in:
parent
20f075a4cf
commit
658e7c98a7
5 changed files with 47 additions and 40 deletions
|
@ -1141,6 +1141,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
const statusIndicator = document.querySelector('.domain__filter-indicator');
|
const statusIndicator = document.querySelector('.domain__filter-indicator');
|
||||||
const statusToggle = document.querySelector('.usa-button--filter');
|
const statusToggle = document.querySelector('.usa-button--filter');
|
||||||
const noPortfolioFlag = document.getElementById('no-portfolio-js-flag');
|
const noPortfolioFlag = document.getElementById('no-portfolio-js-flag');
|
||||||
|
const portfolioElement = document.getElementById('portfolio-js-value');
|
||||||
|
const portfolioValue = portfolioElement ? portfolioElement.getAttribute('data-portfolio') : null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads rows in the domains list, as well as updates pagination around the domains list
|
* Loads rows in the domains list, as well as updates pagination around the domains list
|
||||||
|
@ -1150,10 +1152,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
* @param {*} order - the sort order {asc, desc}
|
* @param {*} order - the sort order {asc, desc}
|
||||||
* @param {*} scroll - control for the scrollToElement functionality
|
* @param {*} scroll - control for the scrollToElement functionality
|
||||||
* @param {*} searchTerm - the search term
|
* @param {*} searchTerm - the search term
|
||||||
|
* @param {*} portfolio - the portfolio id
|
||||||
*/
|
*/
|
||||||
function loadDomains(page, sortBy = currentSortBy, order = currentOrder, scroll = scrollToTable, status = currentStatus, searchTerm = currentSearchTerm) {
|
function loadDomains(page, sortBy = currentSortBy, order = currentOrder, scroll = scrollToTable, status = currentStatus, searchTerm = currentSearchTerm, portfolio = portfolioValue) {
|
||||||
// fetch json of page of domains, given params
|
// fetch json of page of domains, given params
|
||||||
fetch(`/get-domains-json/?page=${page}&sort_by=${sortBy}&order=${order}&status=${status}&search_term=${searchTerm}`)
|
let url = `/get-domains-json/?page=${page}&sort_by=${sortBy}&order=${order}&status=${status}&search_term=${searchTerm}`
|
||||||
|
if (portfolio)
|
||||||
|
url += `&portfolio=${portfolio}`
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
|
|
|
@ -76,11 +76,6 @@ class User(AbstractUser):
|
||||||
|
|
||||||
VIEW_ALL_DOMAINS = "view_all_domains", "View all domains and domain reports"
|
VIEW_ALL_DOMAINS = "view_all_domains", "View all domains and domain reports"
|
||||||
VIEW_MANAGED_DOMAINS = "view_managed_domains", "View managed domains"
|
VIEW_MANAGED_DOMAINS = "view_managed_domains", "View managed domains"
|
||||||
# EDIT_DOMAINS is really self.domains. We add is hear and leverage it in has_permission
|
|
||||||
# so we have one way to test for portfolio and domain edit permissions
|
|
||||||
# Do we need to check for portfolio domains specifically?
|
|
||||||
# NOTE: A user on an org can currently invite a user outside the org
|
|
||||||
EDIT_DOMAINS = "edit_domains", "User is a manager on a domain"
|
|
||||||
|
|
||||||
VIEW_MEMBER = "view_member", "View members"
|
VIEW_MEMBER = "view_member", "View members"
|
||||||
EDIT_MEMBER = "edit_member", "Create and edit members"
|
EDIT_MEMBER = "edit_member", "Create and edit members"
|
||||||
|
@ -268,11 +263,6 @@ class User(AbstractUser):
|
||||||
def _has_portfolio_permission(self, portfolio_permission):
|
def _has_portfolio_permission(self, portfolio_permission):
|
||||||
"""The views should only call this function when testing for perms and not rely on roles."""
|
"""The views should only call this function when testing for perms and not rely on roles."""
|
||||||
|
|
||||||
# EDIT_DOMAINS === user is a manager on a domain (has UserDomainRole)
|
|
||||||
# NOTE: Should we check whether the domain is in the portfolio?
|
|
||||||
if portfolio_permission == self.UserPortfolioPermissionChoices.EDIT_DOMAINS and self.domains.exists():
|
|
||||||
return True
|
|
||||||
|
|
||||||
if not self.portfolio:
|
if not self.portfolio:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -286,21 +276,14 @@ class User(AbstractUser):
|
||||||
return self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO)
|
return self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO)
|
||||||
|
|
||||||
def has_domains_portfolio_permission(self):
|
def has_domains_portfolio_permission(self):
|
||||||
return (
|
return self._has_portfolio_permission(
|
||||||
self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS)
|
User.UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS
|
||||||
or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_MANAGED_DOMAINS)
|
) or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_MANAGED_DOMAINS)
|
||||||
# or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
|
|
||||||
)
|
|
||||||
|
|
||||||
def has_edit_domains_portfolio_permission(self):
|
|
||||||
return self._has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
|
|
||||||
|
|
||||||
def has_domain_requests_portfolio_permission(self):
|
def has_domain_requests_portfolio_permission(self):
|
||||||
return (
|
return self._has_portfolio_permission(
|
||||||
self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS)
|
User.UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS
|
||||||
or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_CREATED_REQUESTS)
|
) or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_CREATED_REQUESTS)
|
||||||
# or self._has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_REQUESTS)
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def needs_identity_verification(cls, email, uuid):
|
def needs_identity_verification(cls, email, uuid):
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
<h2 id="domains-header" class="flex-6">Domains</h2>
|
<h2 id="domains-header" class="flex-6">Domains</h2>
|
||||||
</div>
|
</div>
|
||||||
<span class="display-none" id="no-portfolio-js-flag"></span>
|
<span class="display-none" id="no-portfolio-js-flag"></span>
|
||||||
|
{% else %}
|
||||||
|
<!-- Embedding the portfolio value in a data attribute -->
|
||||||
|
<span id="portfolio-js-value" data-portfolio="{{ portfolio.id }}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="mobile:grid-col-12 desktop:grid-col-6">
|
<div class="mobile:grid-col-12 desktop:grid-col-6">
|
||||||
<section aria-label="Domains search component" class="flex-6 margin-y-2">
|
<section aria-label="Domains search component" class="flex-6 margin-y-2">
|
||||||
|
|
|
@ -1221,7 +1221,6 @@ class TestUser(TestCase):
|
||||||
1. Returns False when a user does not have a portfolio
|
1. Returns False when a user does not have a portfolio
|
||||||
2. Returns True when user has direct permission
|
2. Returns True when user has direct permission
|
||||||
3. Returns True when user has permission through a role
|
3. Returns True when user has permission through a role
|
||||||
4. Returns True EDIT_DOMAINS when user does not have the perm but has UserDomainRole
|
|
||||||
|
|
||||||
Note: This tests _get_portfolio_permissions as a side effect
|
Note: This tests _get_portfolio_permissions as a side effect
|
||||||
"""
|
"""
|
||||||
|
@ -1233,11 +1232,9 @@ class TestUser(TestCase):
|
||||||
|
|
||||||
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
||||||
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
||||||
user_can_edit_domains = self.user.has_edit_domains_portfolio_permission()
|
|
||||||
|
|
||||||
self.assertFalse(user_can_view_all_domains)
|
self.assertFalse(user_can_view_all_domains)
|
||||||
self.assertFalse(user_can_view_all_requests)
|
self.assertFalse(user_can_view_all_requests)
|
||||||
self.assertFalse(user_can_edit_domains)
|
|
||||||
|
|
||||||
self.user.portfolio = portfolio
|
self.user.portfolio = portfolio
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
@ -1245,11 +1242,9 @@ class TestUser(TestCase):
|
||||||
|
|
||||||
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
||||||
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
||||||
user_can_edit_domains = self.user.has_edit_domains_portfolio_permission()
|
|
||||||
|
|
||||||
self.assertTrue(user_can_view_all_domains)
|
self.assertTrue(user_can_view_all_domains)
|
||||||
self.assertFalse(user_can_view_all_requests)
|
self.assertFalse(user_can_view_all_requests)
|
||||||
self.assertFalse(user_can_edit_domains)
|
|
||||||
|
|
||||||
self.user.portfolio_roles = [User.UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
self.user.portfolio_roles = [User.UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
@ -1257,11 +1252,9 @@ class TestUser(TestCase):
|
||||||
|
|
||||||
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
||||||
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
||||||
user_can_edit_domains = self.user.has_edit_domains_portfolio_permission()
|
|
||||||
|
|
||||||
self.assertTrue(user_can_view_all_domains)
|
self.assertTrue(user_can_view_all_domains)
|
||||||
self.assertTrue(user_can_view_all_requests)
|
self.assertTrue(user_can_view_all_requests)
|
||||||
self.assertFalse(user_can_edit_domains)
|
|
||||||
|
|
||||||
UserDomainRole.objects.all().get_or_create(
|
UserDomainRole.objects.all().get_or_create(
|
||||||
user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER
|
user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER
|
||||||
|
@ -1269,11 +1262,9 @@ class TestUser(TestCase):
|
||||||
|
|
||||||
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
user_can_view_all_domains = self.user.has_domains_portfolio_permission()
|
||||||
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
user_can_view_all_requests = self.user.has_domain_requests_portfolio_permission()
|
||||||
user_can_edit_domains = self.user.has_edit_domains_portfolio_permission()
|
|
||||||
|
|
||||||
self.assertTrue(user_can_view_all_domains)
|
self.assertTrue(user_can_view_all_domains)
|
||||||
self.assertTrue(user_can_view_all_requests)
|
self.assertTrue(user_can_view_all_requests)
|
||||||
self.assertTrue(user_can_edit_domains)
|
|
||||||
|
|
||||||
Portfolio.objects.all().delete()
|
Portfolio.objects.all().delete()
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ from django.contrib.auth.decorators import login_required
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from registrar.models.domain_information import DomainInformation
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,10 +16,9 @@ def get_domains_json(request):
|
||||||
"""Given the current request,
|
"""Given the current request,
|
||||||
get all domains that are associated with the UserDomainRole object"""
|
get all domains that are associated with the UserDomainRole object"""
|
||||||
|
|
||||||
user_domain_roles = UserDomainRole.objects.filter(user=request.user).select_related("domain_info__sub_organization")
|
domain_ids = get_domain_ids_from_request(request)
|
||||||
domain_ids = user_domain_roles.values_list("domain_id", flat=True)
|
|
||||||
|
|
||||||
objects = Domain.objects.filter(id__in=domain_ids)
|
objects = Domain.objects.filter(id__in=domain_ids).select_related("domain_info__sub_organization")
|
||||||
unfiltered_total = objects.count()
|
unfiltered_total = objects.count()
|
||||||
|
|
||||||
objects = apply_search(objects, request)
|
objects = apply_search(objects, request)
|
||||||
|
@ -28,7 +29,7 @@ def get_domains_json(request):
|
||||||
page_number = request.GET.get("page")
|
page_number = request.GET.get("page")
|
||||||
page_obj = paginator.get_page(page_number)
|
page_obj = paginator.get_page(page_number)
|
||||||
|
|
||||||
domains = [serialize_domain(domain) for domain in page_obj.object_list]
|
domains = [serialize_domain(domain, request.user) for domain in page_obj.object_list]
|
||||||
|
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
|
@ -43,6 +44,21 @@ def get_domains_json(request):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_domain_ids_from_request(request):
|
||||||
|
"""Get domain ids from request.
|
||||||
|
|
||||||
|
If portfolio specified, return domain ids associated with portfolio.
|
||||||
|
Otherwise, return domain ids associated with request.user.
|
||||||
|
"""
|
||||||
|
portfolio = request.GET.get("portfolio")
|
||||||
|
if portfolio:
|
||||||
|
domain_infos = DomainInformation.objects.filter(portfolio=portfolio)
|
||||||
|
return domain_infos.values_list("domain_id", flat=True)
|
||||||
|
else:
|
||||||
|
user_domain_roles = UserDomainRole.objects.filter(user=request.user)
|
||||||
|
return user_domain_roles.values_list("domain_id", flat=True)
|
||||||
|
|
||||||
|
|
||||||
def apply_search(queryset, request):
|
def apply_search(queryset, request):
|
||||||
search_term = request.GET.get("search_term")
|
search_term = request.GET.get("search_term")
|
||||||
if search_term:
|
if search_term:
|
||||||
|
@ -94,7 +110,7 @@ def apply_sorting(queryset, request):
|
||||||
return queryset.order_by(sort_by)
|
return queryset.order_by(sort_by)
|
||||||
|
|
||||||
|
|
||||||
def serialize_domain(domain):
|
def serialize_domain(domain, user):
|
||||||
suborganization_name = None
|
suborganization_name = None
|
||||||
try:
|
try:
|
||||||
domain_info = domain.domain_info
|
domain_info = domain.domain_info
|
||||||
|
@ -106,6 +122,9 @@ def serialize_domain(domain):
|
||||||
domain_info = None
|
domain_info = None
|
||||||
logger.debug(f"Issue in domains_json: We could not find domain_info for {domain}")
|
logger.debug(f"Issue in domains_json: We could not find domain_info for {domain}")
|
||||||
|
|
||||||
|
# Check if there is a UserDomainRole for this domain and user
|
||||||
|
user_domain_role_exists = UserDomainRole.objects.filter(domain_id=domain.id, user=user).exists()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": domain.id,
|
"id": domain.id,
|
||||||
"name": domain.name,
|
"name": domain.name,
|
||||||
|
@ -114,7 +133,11 @@ def serialize_domain(domain):
|
||||||
"state_display": domain.state_display(),
|
"state_display": domain.state_display(),
|
||||||
"get_state_help_text": domain.get_state_help_text(),
|
"get_state_help_text": domain.get_state_help_text(),
|
||||||
"action_url": reverse("domain", kwargs={"pk": domain.id}),
|
"action_url": reverse("domain", kwargs={"pk": domain.id}),
|
||||||
"action_label": ("View" if domain.state in [Domain.State.DELETED, Domain.State.ON_HOLD] else "Manage"),
|
"action_label": (
|
||||||
|
"View"
|
||||||
|
if not user_domain_role_exists or domain.state in [Domain.State.DELETED, Domain.State.ON_HOLD]
|
||||||
|
else "Manage"
|
||||||
|
),
|
||||||
"svg_icon": ("visibility" if domain.state in [Domain.State.DELETED, Domain.State.ON_HOLD] else "settings"),
|
"svg_icon": ("visibility" if domain.state in [Domain.State.DELETED, Domain.State.ON_HOLD] else "settings"),
|
||||||
"suborganization": suborganization_name,
|
"suborganization": suborganization_name,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue