mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-14 13:34:10 +02:00
portfolio member permissions
This commit is contained in:
parent
e4021b76c1
commit
908e71e3ae
7 changed files with 90 additions and 228 deletions
|
@ -18,6 +18,8 @@ HAS_PORTFOLIO_DOMAINS_VIEW_ALL = "has_portfolio_domains_view_all"
|
||||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM = "has_portfolio_domain_requests_any_perm"
|
HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM = "has_portfolio_domain_requests_any_perm"
|
||||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL = "has_portfolio_domain_requests_view_all"
|
HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL = "has_portfolio_domain_requests_view_all"
|
||||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT = "has_portfolio_domain_requests_edit"
|
HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT = "has_portfolio_domain_requests_edit"
|
||||||
|
HAS_PORTFOLIO_MEMBERS_ANY_PERM = "has_portfolio_members_any_perm"
|
||||||
|
HAS_PORTFOLIO_MEMBERS_EDIT = "has_portfolio_members_edit"
|
||||||
|
|
||||||
|
|
||||||
def grant_access(*rules):
|
def grant_access(*rules):
|
||||||
|
@ -142,6 +144,22 @@ def _user_has_permission(user, request, rules, **kwargs):
|
||||||
print(has_permission)
|
print(has_permission)
|
||||||
conditions_met.append(has_permission)
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
|
if not any(conditions_met) and HAS_PORTFOLIO_MEMBERS_ANY_PERM in rules:
|
||||||
|
portfolio = request.session.get("portfolio")
|
||||||
|
has_permission = user.is_org_user(request) and (
|
||||||
|
user.has_view_members_portfolio_permission(portfolio) or
|
||||||
|
user.has_edit_members_portfolio_permission(portfolio)
|
||||||
|
)
|
||||||
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
|
if not any(conditions_met) and HAS_PORTFOLIO_MEMBERS_EDIT in rules:
|
||||||
|
portfolio = request.session.get("portfolio")
|
||||||
|
has_permission = (
|
||||||
|
user.is_org_user(request) and
|
||||||
|
user.has_edit_members_portfolio_permission(portfolio)
|
||||||
|
)
|
||||||
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
return any(conditions_met)
|
return any(conditions_met)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,37 +4,38 @@ from django.http import JsonResponse
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.views import View
|
from django.views import View
|
||||||
|
from registrar.decorators import HAS_PORTFOLIO_MEMBERS_ANY_PERM, grant_access
|
||||||
from registrar.models import UserDomainRole, Domain, DomainInformation, User
|
from registrar.models import UserDomainRole, Domain, DomainInformation, User
|
||||||
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_invitation import DomainInvitation
|
from registrar.models.domain_invitation import DomainInvitation
|
||||||
from registrar.views.utility.mixins import PortfolioMemberDomainsPermission
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMemberDomainsJson(View):
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
"""Given the current request,
|
"""Given the current request,
|
||||||
get all domains that are associated with the portfolio, or
|
get all domains that are associated with the portfolio, or
|
||||||
associated with the member/invited member"""
|
associated with the member/invited member"""
|
||||||
|
|
||||||
domain_ids = self.get_domain_ids_from_request(request)
|
domain_ids = self._get_domain_ids_from_request(request)
|
||||||
|
|
||||||
objects = Domain.objects.filter(id__in=domain_ids).select_related("domain_info__sub_organization")
|
objects = Domain.objects.filter(id__in=domain_ids).select_related("domain_info__sub_organization")
|
||||||
unfiltered_total = objects.count()
|
unfiltered_total = objects.count()
|
||||||
|
|
||||||
objects = self.apply_search(objects, request)
|
objects = self._apply_search(objects, request)
|
||||||
objects = self.apply_sorting(objects, request)
|
objects = self._apply_sorting(objects, request)
|
||||||
|
|
||||||
paginator = Paginator(objects, self.get_page_size(request))
|
paginator = Paginator(objects, self._get_page_size(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)
|
||||||
|
|
||||||
member_id = request.GET.get("member_id")
|
member_id = request.GET.get("member_id")
|
||||||
domains = [self.serialize_domain(domain, member_id, request.user) for domain in page_obj.object_list]
|
domains = [self._serialize_domain(domain, member_id, request.user) for domain in page_obj.object_list]
|
||||||
|
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
|
@ -48,7 +49,7 @@ class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_page_size(self, request):
|
def _get_page_size(self, request):
|
||||||
"""Gets the page size.
|
"""Gets the page size.
|
||||||
|
|
||||||
If member_only, need to return the entire result set every time, so need
|
If member_only, need to return the entire result set every time, so need
|
||||||
|
@ -65,7 +66,7 @@ class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
||||||
# later
|
# later
|
||||||
return 1000
|
return 1000
|
||||||
|
|
||||||
def get_domain_ids_from_request(self, request):
|
def _get_domain_ids_from_request(self, request):
|
||||||
"""Get domain ids from request.
|
"""Get domain ids from request.
|
||||||
|
|
||||||
request.get.email - email address of invited member
|
request.get.email - email address of invited member
|
||||||
|
@ -100,13 +101,13 @@ class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
||||||
logger.warning("Invalid search criteria, returning empty results list")
|
logger.warning("Invalid search criteria, returning empty results list")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def apply_search(self, queryset, request):
|
def _apply_search(self, queryset, request):
|
||||||
search_term = request.GET.get("search_term")
|
search_term = request.GET.get("search_term")
|
||||||
if search_term:
|
if search_term:
|
||||||
queryset = queryset.filter(Q(name__icontains=search_term))
|
queryset = queryset.filter(Q(name__icontains=search_term))
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def apply_sorting(self, queryset, request):
|
def _apply_sorting(self, queryset, request):
|
||||||
# Get the sorting parameters from the request
|
# Get the sorting parameters from the request
|
||||||
sort_by = request.GET.get("sort_by", "name")
|
sort_by = request.GET.get("sort_by", "name")
|
||||||
order = request.GET.get("order", "asc")
|
order = request.GET.get("order", "asc")
|
||||||
|
@ -141,7 +142,7 @@ class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def serialize_domain(self, domain, member_id, user):
|
def _serialize_domain(self, domain, member_id, user):
|
||||||
suborganization_name = None
|
suborganization_name = None
|
||||||
try:
|
try:
|
||||||
domain_info = domain.domain_info
|
domain_info = domain.domain_info
|
||||||
|
@ -176,7 +177,7 @@ class PortfolioMemberDomainsJson(PortfolioMemberDomainsPermission, View):
|
||||||
"state": domain.state,
|
"state": domain.state,
|
||||||
"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={"domain_pk": domain.id}),
|
||||||
"action_label": ("View" if view_only else "Manage"),
|
"action_label": ("View" if view_only else "Manage"),
|
||||||
"svg_icon": ("visibility" if view_only else "settings"),
|
"svg_icon": ("visibility" if view_only else "settings"),
|
||||||
"domain_info__sub_organization": suborganization_name,
|
"domain_info__sub_organization": suborganization_name,
|
||||||
|
|
|
@ -6,16 +6,17 @@ from django.contrib.postgres.aggregates import ArrayAgg
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.views import View
|
from django.views import View
|
||||||
|
|
||||||
|
from registrar.decorators import HAS_PORTFOLIO_MEMBERS_ANY_PERM, grant_access
|
||||||
from registrar.models.domain_invitation import DomainInvitation
|
from registrar.models.domain_invitation import DomainInvitation
|
||||||
from registrar.models.portfolio_invitation import PortfolioInvitation
|
from registrar.models.portfolio_invitation import PortfolioInvitation
|
||||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||||
from registrar.views.utility.mixins import PortfolioMembersPermission
|
|
||||||
from registrar.models.utility.orm_helper import ArrayRemoveNull
|
from registrar.models.utility.orm_helper import ArrayRemoveNull
|
||||||
from django.contrib.postgres.aggregates import StringAgg
|
from django.contrib.postgres.aggregates import StringAgg
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMembersJson(PortfolioMembersPermission, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMembersJson(View):
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
"""Fetch members (permissions and invitations) for the given portfolio."""
|
"""Fetch members (permissions and invitations) for the given portfolio."""
|
||||||
|
@ -236,7 +237,7 @@ class PortfolioMembersJson(PortfolioMembersPermission, View):
|
||||||
),
|
),
|
||||||
# split domain_info array values into ids to form urls, and names
|
# split domain_info array values into ids to form urls, and names
|
||||||
"domain_urls": [
|
"domain_urls": [
|
||||||
reverse("domain", kwargs={"pk": domain_info.split(":")[0]}) for domain_info in domain_info_list
|
reverse("domain", kwargs={"domain_pk": domain_info.split(":")[0]}) for domain_info in domain_info_list
|
||||||
],
|
],
|
||||||
"domain_names": [domain_info.split(":")[1] for domain_info in domain_info_list],
|
"domain_names": [domain_info.split(":")[1] for domain_info in domain_info_list],
|
||||||
"is_admin": is_admin,
|
"is_admin": is_admin,
|
||||||
|
|
|
@ -5,20 +5,26 @@ from django.http import Http404, JsonResponse
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
from django.views.generic import DetailView
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from registrar.decorators import (
|
from registrar.decorators import (
|
||||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM,
|
HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM,
|
||||||
HAS_PORTFOLIO_DOMAINS_ANY_PERM,
|
HAS_PORTFOLIO_DOMAINS_ANY_PERM,
|
||||||
|
HAS_PORTFOLIO_MEMBERS_ANY_PERM,
|
||||||
|
HAS_PORTFOLIO_MEMBERS_EDIT,
|
||||||
IS_PORTFOLIO_MEMBER,
|
IS_PORTFOLIO_MEMBER,
|
||||||
grant_access,
|
grant_access,
|
||||||
)
|
)
|
||||||
from registrar.forms import portfolio as portfolioForms
|
from registrar.forms import portfolio as portfolioForms
|
||||||
from registrar.models import Portfolio, User
|
from registrar.models import (
|
||||||
from registrar.models.domain import Domain
|
Domain,
|
||||||
from registrar.models.domain_invitation import DomainInvitation
|
DomainInvitation,
|
||||||
from registrar.models.portfolio_invitation import PortfolioInvitation
|
Portfolio,
|
||||||
from registrar.models.user_domain_role import UserDomainRole
|
PortfolioInvitation,
|
||||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
User,
|
||||||
|
UserDomainRole,
|
||||||
|
UserPortfolioPermission
|
||||||
|
)
|
||||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||||
from registrar.utility.email import EmailSendingError
|
from registrar.utility.email import EmailSendingError
|
||||||
from registrar.utility.email_invitations import (
|
from registrar.utility.email_invitations import (
|
||||||
|
@ -29,15 +35,6 @@ from registrar.utility.email_invitations import (
|
||||||
)
|
)
|
||||||
from registrar.utility.errors import MissingEmailError
|
from registrar.utility.errors import MissingEmailError
|
||||||
from registrar.utility.enums import DefaultUserValues
|
from registrar.utility.enums import DefaultUserValues
|
||||||
from registrar.views.utility.mixins import PortfolioMemberPermission
|
|
||||||
from registrar.views.utility.permission_views import (
|
|
||||||
PortfolioBasePermissionView,
|
|
||||||
PortfolioMemberDomainsPermissionView,
|
|
||||||
PortfolioMemberDomainsEditPermissionView,
|
|
||||||
PortfolioMemberEditPermissionView,
|
|
||||||
PortfolioMemberPermissionView,
|
|
||||||
PortfolioMembersPermissionView,
|
|
||||||
)
|
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.views.generic.edit import FormMixin
|
from django.views.generic.edit import FormMixin
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
|
@ -71,8 +68,10 @@ class PortfolioDomainRequestsView(View):
|
||||||
return render(request, "portfolio_requests.html")
|
return render(request, "portfolio_requests.html")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberView(PortfolioMemberPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMemberView(DetailView, View):
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member.html"
|
template_name = "portfolio_member.html"
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
@ -113,7 +112,8 @@ class PortfolioMemberView(PortfolioMemberPermissionView, View):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMemberDeleteView(View):
|
||||||
|
|
||||||
def post(self, request, pk):
|
def post(self, request, pk):
|
||||||
"""
|
"""
|
||||||
|
@ -190,8 +190,10 @@ class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
|
||||||
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberEditView(PortfolioMemberEditPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT)
|
||||||
|
class PortfolioMemberEditView(DetailView, View):
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member_permissions.html"
|
template_name = "portfolio_member_permissions.html"
|
||||||
form_class = portfolioForms.PortfolioMemberForm
|
form_class = portfolioForms.PortfolioMemberForm
|
||||||
|
|
||||||
|
@ -265,7 +267,8 @@ class PortfolioMemberEditView(PortfolioMemberEditPermissionView, View):
|
||||||
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsView(PortfolioMemberDomainsPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMemberDomainsView(View):
|
||||||
|
|
||||||
template_name = "portfolio_member_domains.html"
|
template_name = "portfolio_member_domains.html"
|
||||||
|
|
||||||
|
@ -283,8 +286,10 @@ class PortfolioMemberDomainsView(PortfolioMemberDomainsPermissionView, View):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsEditView(PortfolioMemberDomainsEditPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT)
|
||||||
|
class PortfolioMemberDomainsEditView(DetailView, View):
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member_domains_edit.html"
|
template_name = "portfolio_member_domains_edit.html"
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
@ -393,8 +398,10 @@ class PortfolioMemberDomainsEditView(PortfolioMemberDomainsEditPermissionView, V
|
||||||
UserDomainRole.objects.filter(domain_id__in=removed_domain_ids, user=member).delete()
|
UserDomainRole.objects.filter(domain_id__in=removed_domain_ids, user=member).delete()
|
||||||
|
|
||||||
|
|
||||||
class PortfolioInvitedMemberView(PortfolioMemberPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioInvitedMemberView(DetailView, View):
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member.html"
|
template_name = "portfolio_member.html"
|
||||||
# form_class = PortfolioInvitedMemberForm
|
# form_class = PortfolioInvitedMemberForm
|
||||||
|
|
||||||
|
@ -435,7 +442,8 @@ class PortfolioInvitedMemberView(PortfolioMemberPermissionView, View):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PortfolioInvitedMemberDeleteView(PortfolioMemberPermission, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioInvitedMemberDeleteView(View):
|
||||||
|
|
||||||
def post(self, request, pk):
|
def post(self, request, pk):
|
||||||
"""
|
"""
|
||||||
|
@ -478,8 +486,10 @@ class PortfolioInvitedMemberDeleteView(PortfolioMemberPermission, View):
|
||||||
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioInvitedMemberEditView(PortfolioMemberEditPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT)
|
||||||
|
class PortfolioInvitedMemberEditView(DetailView, View):
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member_permissions.html"
|
template_name = "portfolio_member_permissions.html"
|
||||||
form_class = portfolioForms.PortfolioInvitedMemberForm
|
form_class = portfolioForms.PortfolioInvitedMemberForm
|
||||||
|
|
||||||
|
@ -547,7 +557,8 @@ class PortfolioInvitedMemberEditView(PortfolioMemberEditPermissionView, View):
|
||||||
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
messages.warning(self.request, "Could not send email notification to existing organization admins.")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioInvitedMemberDomainsView(PortfolioMemberDomainsPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioInvitedMemberDomainsView(View):
|
||||||
|
|
||||||
template_name = "portfolio_member_domains.html"
|
template_name = "portfolio_member_domains.html"
|
||||||
|
|
||||||
|
@ -562,9 +573,11 @@ class PortfolioInvitedMemberDomainsView(PortfolioMemberDomainsPermissionView, Vi
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@grant_access(HAS_PORTFOLIO_MEMBERS_EDIT)
|
||||||
|
class PortfolioInvitedMemberDomainsEditView(DetailView, View):
|
||||||
|
|
||||||
class PortfolioInvitedMemberDomainsEditView(PortfolioMemberDomainsEditPermissionView, View):
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
template_name = "portfolio_member_domains_edit.html"
|
template_name = "portfolio_member_domains_edit.html"
|
||||||
|
|
||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
@ -749,7 +762,8 @@ class PortfolioNoDomainRequestsView(View):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class PortfolioOrganizationView(PortfolioBasePermissionView, FormMixin):
|
@grant_access(IS_PORTFOLIO_MEMBER)
|
||||||
|
class PortfolioOrganizationView(DetailView, FormMixin):
|
||||||
"""
|
"""
|
||||||
View to handle displaying and updating the portfolio's organization details.
|
View to handle displaying and updating the portfolio's organization details.
|
||||||
"""
|
"""
|
||||||
|
@ -811,7 +825,8 @@ class PortfolioOrganizationView(PortfolioBasePermissionView, FormMixin):
|
||||||
return reverse("organization")
|
return reverse("organization")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioSeniorOfficialView(PortfolioBasePermissionView, FormMixin):
|
@grant_access(IS_PORTFOLIO_MEMBER)
|
||||||
|
class PortfolioSeniorOfficialView(DetailView, FormMixin):
|
||||||
"""
|
"""
|
||||||
View to handle displaying and updating the portfolio's senior official details.
|
View to handle displaying and updating the portfolio's senior official details.
|
||||||
For now, this view is readonly.
|
For now, this view is readonly.
|
||||||
|
@ -842,7 +857,8 @@ class PortfolioSeniorOfficialView(PortfolioBasePermissionView, FormMixin):
|
||||||
return self.render_to_response(self.get_context_data(form=form))
|
return self.render_to_response(self.get_context_data(form=form))
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMembersView(PortfolioMembersPermissionView, View):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioMembersView(View):
|
||||||
|
|
||||||
template_name = "portfolio_members.html"
|
template_name = "portfolio_members.html"
|
||||||
|
|
||||||
|
@ -851,10 +867,13 @@ class PortfolioMembersView(PortfolioMembersPermissionView, View):
|
||||||
return render(request, "portfolio_members.html")
|
return render(request, "portfolio_members.html")
|
||||||
|
|
||||||
|
|
||||||
class PortfolioAddMemberView(PortfolioMembersPermissionView, FormMixin):
|
@grant_access(HAS_PORTFOLIO_MEMBERS_ANY_PERM)
|
||||||
|
class PortfolioAddMemberView(DetailView, FormMixin):
|
||||||
|
|
||||||
template_name = "portfolio_members_add_new.html"
|
template_name = "portfolio_members_add_new.html"
|
||||||
form_class = portfolioForms.PortfolioNewMemberForm
|
form_class = portfolioForms.PortfolioNewMemberForm
|
||||||
|
model = Portfolio
|
||||||
|
context_object_name = "portfolio"
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
"""Handle GET requests to display the form."""
|
"""Handle GET requests to display the form."""
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
from .steps_helper import StepsHelper
|
from .steps_helper import StepsHelper
|
||||||
from .always_404 import always_404
|
from .always_404 import always_404
|
||||||
|
|
||||||
from .permission_views import (
|
|
||||||
PortfolioMembersPermission,
|
|
||||||
)
|
|
||||||
from .api_views import get_senior_official_from_federal_agency_json
|
from .api_views import get_senior_official_from_federal_agency_json
|
||||||
|
|
|
@ -202,110 +202,3 @@ class UserProfilePermission(PermissionsLoginMixin):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class PortfolioBasePermission(PermissionsLoginMixin):
|
|
||||||
"""Permission mixin that redirects to portfolio pages if user
|
|
||||||
has access, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]
|
|
||||||
"""
|
|
||||||
if not self.request.user.is_authenticated:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return self.request.user.is_org_user(self.request)
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMembersPermission(PortfolioBasePermission):
|
|
||||||
"""Permission mixin that allows access to portfolio members pages if user
|
|
||||||
has access, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to members for this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
|
||||||
if not self.request.user.has_view_members_portfolio_permission(
|
|
||||||
portfolio
|
|
||||||
) and not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return super().has_permission()
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberPermission(PortfolioBasePermission):
|
|
||||||
"""Permission mixin that allows access to portfolio member or invited member pages if user
|
|
||||||
has access, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to members or invited members for this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
|
||||||
if not self.request.user.has_view_members_portfolio_permission(
|
|
||||||
portfolio
|
|
||||||
) and not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return super().has_permission()
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberEditPermission(PortfolioBasePermission):
|
|
||||||
"""Permission mixin that allows access to portfolio member or invited member pages if user
|
|
||||||
has access to edit, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to members or invited members for this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
|
||||||
if not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return super().has_permission()
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsPermission(PortfolioBasePermission):
|
|
||||||
"""Permission mixin that allows access to portfolio member or invited member domains pages if user
|
|
||||||
has access to edit, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to member or invited member domains for this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
|
||||||
if not self.request.user.has_view_members_portfolio_permission(
|
|
||||||
portfolio
|
|
||||||
) and not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return super().has_permission()
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsEditPermission(PortfolioBasePermission):
|
|
||||||
"""Permission mixin that allows access to portfolio member or invited member domains edit pages if user
|
|
||||||
has access to edit, otherwise 403"""
|
|
||||||
|
|
||||||
def has_permission(self):
|
|
||||||
"""Check if this user has access to member or invited member domains for this portfolio.
|
|
||||||
|
|
||||||
The user is in self.request.user and the portfolio can be looked
|
|
||||||
up from the portfolio's primary key in self.kwargs["pk"]"""
|
|
||||||
|
|
||||||
portfolio = self.request.session.get("portfolio")
|
|
||||||
if not self.request.user.has_edit_members_portfolio_permission(portfolio):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return super().has_permission()
|
|
||||||
|
|
|
@ -7,13 +7,7 @@ from registrar.models import Portfolio
|
||||||
from registrar.models.user import User
|
from registrar.models.user import User
|
||||||
|
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
PortfolioMemberDomainsPermission,
|
|
||||||
PortfolioMemberDomainsEditPermission,
|
|
||||||
PortfolioMemberEditPermission,
|
|
||||||
UserProfilePermission,
|
UserProfilePermission,
|
||||||
PortfolioBasePermission,
|
|
||||||
PortfolioMembersPermission,
|
|
||||||
PortfolioMemberPermission,
|
|
||||||
)
|
)
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -37,64 +31,3 @@ class UserProfilePermissionView(UserProfilePermission, DetailView, abc.ABC):
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def template_name(self):
|
def template_name(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class PortfolioBasePermissionView(PortfolioBasePermission, DetailView, abc.ABC):
|
|
||||||
"""Abstract base view for portfolio views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# DetailView property for what model this is viewing
|
|
||||||
model = Portfolio
|
|
||||||
# variable name in template context for the model object
|
|
||||||
context_object_name = "portfolio"
|
|
||||||
|
|
||||||
# Abstract property enforces NotImplementedError on an attribute.
|
|
||||||
@property
|
|
||||||
@abc.abstractmethod
|
|
||||||
def template_name(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMembersPermissionView(PortfolioMembersPermission, PortfolioBasePermissionView, abc.ABC):
|
|
||||||
"""Abstract base view for portfolio members views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberPermissionView(PortfolioMemberPermission, PortfolioBasePermissionView, abc.ABC):
|
|
||||||
"""Abstract base view for portfolio member views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberEditPermissionView(PortfolioMemberEditPermission, PortfolioBasePermissionView, abc.ABC):
|
|
||||||
"""Abstract base view for portfolio member edit views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsPermissionView(PortfolioMemberDomainsPermission, PortfolioBasePermissionView, abc.ABC):
|
|
||||||
"""Abstract base view for portfolio member domains views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class PortfolioMemberDomainsEditPermissionView(
|
|
||||||
PortfolioMemberDomainsEditPermission, PortfolioBasePermissionView, abc.ABC
|
|
||||||
):
|
|
||||||
"""Abstract base view for portfolio member domains edit views that enforces permissions.
|
|
||||||
|
|
||||||
This abstract view cannot be instantiated. Actual views must specify
|
|
||||||
`template_name`.
|
|
||||||
"""
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue