mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-14 21:44:08 +02:00
added decorators for domain requests, ignored __debug, update domain request pks
This commit is contained in:
parent
bd071a0fb3
commit
6269cc56e3
15 changed files with 112 additions and 289 deletions
|
@ -68,7 +68,7 @@ for step, view in [
|
|||
(PortfolioDomainRequestStep.REQUESTING_ENTITY, views.RequestingEntity),
|
||||
(PortfolioDomainRequestStep.ADDITIONAL_DETAILS, views.PortfolioAdditionalDetails),
|
||||
]:
|
||||
domain_request_urls.append(path(f"<int:id>/{step}/", view.as_view(), name=step))
|
||||
domain_request_urls.append(path(f"<int:domain_request_pk>/{step}/", view.as_view(), name=step))
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -260,27 +260,27 @@ urlpatterns = [
|
|||
name="export_data_type_user",
|
||||
),
|
||||
path(
|
||||
"domain-request/<int:id>/edit/",
|
||||
"domain-request/<int:domain_request_pk>/edit/",
|
||||
views.DomainRequestWizard.as_view(),
|
||||
name=views.DomainRequestWizard.EDIT_URL_NAME,
|
||||
),
|
||||
path(
|
||||
"domain-request/<int:pk>",
|
||||
"domain-request/<int:domain_request_pk>",
|
||||
views.DomainRequestStatus.as_view(),
|
||||
name="domain-request-status",
|
||||
),
|
||||
path(
|
||||
"domain-request/viewonly/<int:pk>",
|
||||
"domain-request/viewonly/<int:domain_request_pk>",
|
||||
views.PortfolioDomainRequestStatusViewOnly.as_view(),
|
||||
name="domain-request-status-viewonly",
|
||||
),
|
||||
path(
|
||||
"domain-request/<int:pk>/withdraw",
|
||||
"domain-request/<int:domain_request_pk>/withdraw",
|
||||
views.DomainRequestWithdrawConfirmation.as_view(),
|
||||
name="domain-request-withdraw-confirmation",
|
||||
),
|
||||
path(
|
||||
"domain-request/<int:pk>/withdrawconfirmed",
|
||||
"domain-request/<int:domain_request_pk>/withdrawconfirmed",
|
||||
views.DomainRequestWithdrawn.as_view(),
|
||||
name="domain-request-withdrawn",
|
||||
),
|
||||
|
@ -369,7 +369,7 @@ urlpatterns = [
|
|||
name="invitation-cancel",
|
||||
),
|
||||
path(
|
||||
"domain-request/<int:pk>/delete",
|
||||
"domain-request/<int:domain_request_pk>/delete",
|
||||
views.DomainRequestDeleteView.as_view(http_method_names=["post"]),
|
||||
name="domain-request-delete",
|
||||
),
|
||||
|
|
|
@ -8,10 +8,14 @@ ALL = "all"
|
|||
IS_SUPERUSER = "is_superuser"
|
||||
IS_STAFF = "is_staff"
|
||||
IS_DOMAIN_MANAGER = "is_domain_manager"
|
||||
IS_DOMAIN_REQUEST_CREATOR = "is_domain_request_creator"
|
||||
IS_STAFF_MANAGING_DOMAIN = "is_staff_managing_domain"
|
||||
IS_PORTFOLIO_MEMBER_AND_DOMAIN_MANAGER = "is_portfolio_member_and_domain_manager"
|
||||
IS_DOMAIN_MANAGER_AND_NOT_PORTFOLIO_MEMBER = "is_domain_manager_and_not_portfolio_member"
|
||||
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_VIEW_ALL = "has_portfolio_domain_requests_view_all"
|
||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT = "has_portfolio_domain_requests_edit"
|
||||
# HAS_PORTFOLIO_DOMAINS_VIEW_MANAGED = "has_portfolio_domains_view_managed"
|
||||
|
||||
|
||||
|
@ -108,15 +112,52 @@ def _user_has_permission(user, request, rules, **kwargs):
|
|||
has_permission = _is_domain_manager(user, domain_id) and not _is_portfolio_member(request)
|
||||
conditions_met.append(has_permission)
|
||||
|
||||
if not any(conditions_met) and IS_DOMAIN_REQUEST_CREATOR in rules:
|
||||
domain_request_id = kwargs.get("domain_request_pk")
|
||||
has_permission = _is_domain_request_creator(user, domain_request_id)
|
||||
conditions_met.append(has_permission)
|
||||
|
||||
if not any(conditions_met) and HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM in rules:
|
||||
has_permission = user.is_org_user(request) and user.has_any_requests_portfolio_permission(
|
||||
request.session.get("portfolio")
|
||||
)
|
||||
conditions_met.append(has_permission)
|
||||
|
||||
if not any(conditions_met) and HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL in rules:
|
||||
has_permission = user.is_org_user(request) and user.has_view_all_domain_requests_portfolio_permission(
|
||||
request.session.get("portfolio")
|
||||
)
|
||||
conditions_met.append(has_permission)
|
||||
|
||||
if not any(conditions_met) and HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT in rules:
|
||||
domain_request_id = kwargs.get("domain_request_pk")
|
||||
has_permission = _has_portfolio_domain_requests_edit(user, request, domain_request_id)
|
||||
print(has_permission)
|
||||
conditions_met.append(has_permission)
|
||||
|
||||
return any(conditions_met)
|
||||
|
||||
|
||||
def _has_portfolio_domain_requests_edit(user, request, domain_request_id):
|
||||
if domain_request_id and not _is_domain_request_creator(user, domain_request_id):
|
||||
return False
|
||||
return user.is_org_user(request) and user.has_edit_request_portfolio_permission(request.session.get("portfolio"))
|
||||
|
||||
|
||||
def _is_domain_manager(user, domain_pk):
|
||||
"""Checks to see if the user is a domain manager of the
|
||||
domain with domain_pk."""
|
||||
return UserDomainRole.objects.filter(user=user, domain_id=domain_pk).exists()
|
||||
|
||||
|
||||
def _is_domain_request_creator(user, domain_request_pk):
|
||||
"""Checks to see if the user is the creator of a domain request
|
||||
with domain_request_pk."""
|
||||
if domain_request_pk:
|
||||
return DomainRequest.objects.filter(creator=user, id=domain_request_pk).exists()
|
||||
return True
|
||||
|
||||
|
||||
def _is_portfolio_member(request):
|
||||
"""Checks to see if the user in the request is a member of the
|
||||
portfolio in the request's session."""
|
||||
|
|
|
@ -184,6 +184,11 @@ class RestrictAccessMiddleware:
|
|||
self.ignored_paths = [re.compile(pattern) for pattern in getattr(settings, "LOGIN_REQUIRED_IGNORE_PATHS", [])]
|
||||
|
||||
def __call__(self, request):
|
||||
|
||||
# Allow Django Debug Toolbar requests
|
||||
if request.path.startswith("/__debug__/"):
|
||||
return self.get_response(request)
|
||||
|
||||
# Allow requests that match LOGIN_REQUIRED_IGNORE_PATHS
|
||||
if any(pattern.match(request.path) for pattern in self.ignored_paths):
|
||||
return self.get_response(request)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</ol>
|
||||
</nav>
|
||||
{% elif steps.prev %}
|
||||
<a href="{% namespaced_url 'domain-request' steps.prev id=domain_request_id %}" class="breadcrumb__back">
|
||||
<a href="{% namespaced_url 'domain-request' steps.prev domain_request_pk=domain_request_id %}" class="breadcrumb__back">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||
<use xlink:href="{%static 'img/sprite.svg'%}#arrow_back"></use>
|
||||
</svg><span class="margin-left-05">Previous step</span>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</svg>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="{% namespaced_url 'domain-request' this_step id=domain_request_id %}"
|
||||
<a href="{% namespaced_url 'domain-request' this_step domain_request_pk=domain_request_id %}"
|
||||
{% if this_step == steps.current %}
|
||||
class="usa-current"
|
||||
{% else %}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
<p>If you withdraw your request, we won't review it. Once you withdraw your request, you can edit it and submit it again. </p>
|
||||
|
||||
<p><a href="{% url 'domain-request-withdrawn' DomainRequest.id %}" class="usa-button withdraw">Withdraw request</a>
|
||||
<a href="{% url 'domain-request-status' DomainRequest.id %}">Cancel</a></p>
|
||||
<p><a href="{% url 'domain-request-withdrawn' domain_request_pk=DomainRequest.id %}" class="usa-button withdraw">Withdraw request</a>
|
||||
<a href="{% url 'domain-request-status' domain_request_pk=DomainRequest.id %}">Cancel</a></p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% for step in steps %}
|
||||
<section class="summary-item margin-top-3">
|
||||
{% if is_editable %}
|
||||
{% namespaced_url 'domain-request' step id=domain_request_id as domain_request_url %}
|
||||
{% namespaced_url 'domain-request' step domain_request_pk=domain_request_id as domain_request_url %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.REQUESTING_ENTITY %}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% for step in steps %}
|
||||
<section class="summary-item margin-top-3">
|
||||
{% if is_editable %}
|
||||
{% namespaced_url 'domain-request' step id=domain_request_id as domain_request_url %}
|
||||
{% namespaced_url 'domain-request' step domain_request_pk=domain_request_id as domain_request_url %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.ORGANIZATION_TYPE %}
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
|
||||
{% block modify_request %}
|
||||
{% if DomainRequest.is_withdrawable %}
|
||||
<p><a href="{% url 'domain-request-withdraw-confirmation' pk=DomainRequest.id %}" class="usa-button usa-button--outline withdraw_outline">
|
||||
<p><a href="{% url 'domain-request-withdraw-confirmation' domain_request_pk=DomainRequest.id %}" class="usa-button usa-button--outline withdraw_outline">
|
||||
Withdraw request</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
|
|
@ -5,28 +5,27 @@ from django.shortcuts import redirect, render
|
|||
from django.urls import resolve, reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic import DeleteView, DetailView, TemplateView
|
||||
from django.contrib import messages
|
||||
from registrar.decorators import (
|
||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT,
|
||||
HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL,
|
||||
IS_DOMAIN_REQUEST_CREATOR,
|
||||
grant_access,
|
||||
)
|
||||
from registrar.forms import domain_request_wizard as forms
|
||||
from registrar.forms.utility.wizard_form_helper import request_step_list
|
||||
from registrar.models import DomainRequest
|
||||
from registrar.models.contact import Contact
|
||||
from registrar.models.user import User
|
||||
from registrar.views.utility import StepsHelper
|
||||
from registrar.views.utility.permission_views import DomainRequestPermissionDeleteView
|
||||
from registrar.utility.enums import Step, PortfolioDomainRequestStep
|
||||
|
||||
from .utility import (
|
||||
DomainRequestPermissionView,
|
||||
DomainRequestPermissionWithdrawView,
|
||||
DomainRequestWizardPermissionView,
|
||||
DomainRequestPortfolioViewonlyView,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
||||
@grant_access(IS_DOMAIN_REQUEST_CREATOR, HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT)
|
||||
class DomainRequestWizard(TemplateView):
|
||||
"""
|
||||
A common set of methods and configuration.
|
||||
|
||||
|
@ -51,7 +50,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
# NB: this is included here for reference. Do not change it without
|
||||
# also changing the many places it is hardcoded in the HTML templates
|
||||
URL_NAMESPACE = "domain-request"
|
||||
# name for accessing /domain-request/<id>/edit
|
||||
# name for accessing /domain-request/<domain_request_pk>/edit
|
||||
EDIT_URL_NAME = "edit-domain-request"
|
||||
NEW_URL_NAME = "start"
|
||||
FINISHED_URL_NAME = "finished"
|
||||
|
@ -174,7 +173,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
|
||||
def has_pk(self):
|
||||
"""Does this wizard know about a DomainRequest database record?"""
|
||||
return bool(self.kwargs.get("id") is not None)
|
||||
return bool(self.kwargs.get("domain_request_pk") is not None)
|
||||
|
||||
def get_step_enum(self):
|
||||
"""Determines which step enum we should use for the wizard"""
|
||||
|
@ -209,11 +208,11 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
try:
|
||||
self._domain_request = DomainRequest.objects.get(
|
||||
creator=creator,
|
||||
pk=self.kwargs.get("id"),
|
||||
pk=self.kwargs.get("domain_request_pk"),
|
||||
)
|
||||
return self._domain_request
|
||||
except DomainRequest.DoesNotExist:
|
||||
logger.debug("DomainRequest id %s did not have a DomainRequest" % id)
|
||||
logger.debug("DomainRequest id %s did not have a DomainRequest" % self.kwargs.get("domain_request_pk"))
|
||||
|
||||
# If a user is creating a request, we assume that perms are handled upstream
|
||||
if self.request.user.is_org_user(self.request):
|
||||
|
@ -292,10 +291,10 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
|
||||
current_url = resolve(request.path_info).url_name
|
||||
|
||||
# if user visited via an "edit" url, associate the id of the
|
||||
# if user visited via an "edit" url, associate the pk of the
|
||||
# domain request they are trying to edit to this wizard instance
|
||||
# and remove any prior wizard data from their session
|
||||
if current_url == self.EDIT_URL_NAME and "id" in kwargs:
|
||||
if current_url == self.EDIT_URL_NAME and "domain_request_pk" in kwargs:
|
||||
del self.storage
|
||||
|
||||
# if accessing this class directly, redirect to either to an acknowledgement
|
||||
|
@ -474,7 +473,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
|
||||
def goto(self, step):
|
||||
self.steps.current = step
|
||||
return redirect(reverse(f"{self.URL_NAMESPACE}:{step}", kwargs={"id": self.domain_request.id}))
|
||||
return redirect(reverse(f"{self.URL_NAMESPACE}:{step}", kwargs={"domain_request_pk": self.domain_request.id}))
|
||||
|
||||
def goto_next_step(self):
|
||||
"""Redirects to the next step."""
|
||||
|
@ -823,23 +822,12 @@ class Finished(DomainRequestWizard):
|
|||
return render(self.request, self.template_name, context)
|
||||
|
||||
|
||||
class DomainRequestStatus(DomainRequestPermissionView):
|
||||
@grant_access(IS_DOMAIN_REQUEST_CREATOR, HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT)
|
||||
class DomainRequestStatus(DetailView):
|
||||
template_name = "domain_request_status.html"
|
||||
|
||||
def has_permission(self):
|
||||
"""
|
||||
Override of the base has_permission class to account for portfolio permissions
|
||||
"""
|
||||
has_base_perms = super().has_permission()
|
||||
if not has_base_perms:
|
||||
return False
|
||||
|
||||
if self.request.user.is_org_user(self.request):
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
if not self.request.user.has_edit_request_portfolio_permission(portfolio):
|
||||
return False
|
||||
|
||||
return True
|
||||
model = DomainRequest
|
||||
pk_url_kwarg = "domain_request_pk"
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""Context override to add a step list to the context"""
|
||||
|
@ -854,19 +842,27 @@ class DomainRequestStatus(DomainRequestPermissionView):
|
|||
return context
|
||||
|
||||
|
||||
class DomainRequestWithdrawConfirmation(DomainRequestPermissionWithdrawView):
|
||||
@grant_access(IS_DOMAIN_REQUEST_CREATOR)
|
||||
class DomainRequestWithdrawConfirmation(DetailView):
|
||||
"""This page will ask user to confirm if they want to withdraw
|
||||
|
||||
The DomainRequestPermissionView restricts access so that only the
|
||||
Access is restricted so that only the
|
||||
`creator` of the domain request may withdraw it.
|
||||
"""
|
||||
|
||||
template_name = "domain_request_withdraw_confirmation.html"
|
||||
template_name = "domain_request_withdraw_confirmation.html" # DetailView property for what model this is viewing
|
||||
model = DomainRequest
|
||||
pk_url_kwarg = "domain_request_pk"
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
|
||||
class DomainRequestWithdrawn(DomainRequestPermissionWithdrawView):
|
||||
@grant_access(IS_DOMAIN_REQUEST_CREATOR)
|
||||
class DomainRequestWithdrawn(DetailView):
|
||||
# this view renders no template
|
||||
template_name = ""
|
||||
model = DomainRequest
|
||||
pk_url_kwarg = "domain_request_pk"
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""View class that does the actual withdrawing.
|
||||
|
@ -874,7 +870,7 @@ class DomainRequestWithdrawn(DomainRequestPermissionWithdrawView):
|
|||
If user click on withdraw confirm button, this view updates the status
|
||||
to withdraw and send back to homepage.
|
||||
"""
|
||||
domain_request = DomainRequest.objects.get(id=self.kwargs["pk"])
|
||||
domain_request = DomainRequest.objects.get(id=self.kwargs["domain_request_pk"])
|
||||
domain_request.withdraw()
|
||||
domain_request.save()
|
||||
if self.request.user.is_org_user(self.request):
|
||||
|
@ -883,28 +879,22 @@ class DomainRequestWithdrawn(DomainRequestPermissionWithdrawView):
|
|||
return HttpResponseRedirect(reverse("home"))
|
||||
|
||||
|
||||
class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
||||
@grant_access(IS_DOMAIN_REQUEST_CREATOR, HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT)
|
||||
class DomainRequestDeleteView(DeleteView):
|
||||
"""Delete view for home that allows the end user to delete DomainRequests"""
|
||||
|
||||
object: DomainRequest # workaround for type mismatch in DeleteView
|
||||
model = DomainRequest
|
||||
pk_url_kwarg = "domain_request_pk"
|
||||
|
||||
def has_permission(self):
|
||||
"""Custom override for has_permission to exclude all statuses, except WITHDRAWN and STARTED"""
|
||||
has_perm = super().has_permission()
|
||||
if not has_perm:
|
||||
return False
|
||||
|
||||
status = self.get_object().status
|
||||
valid_statuses = [DomainRequest.DomainRequestStatus.WITHDRAWN, DomainRequest.DomainRequestStatus.STARTED]
|
||||
if status not in valid_statuses:
|
||||
return False
|
||||
|
||||
# Portfolio users cannot delete their requests if they aren't permissioned to do so
|
||||
if self.request.user.is_org_user(self.request):
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
if not self.request.user.has_edit_request_portfolio_permission(portfolio):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def get_success_url(self):
|
||||
|
@ -989,8 +979,12 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
|||
|
||||
|
||||
# region Portfolio views
|
||||
class PortfolioDomainRequestStatusViewOnly(DomainRequestPortfolioViewonlyView):
|
||||
@grant_access(HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL)
|
||||
class PortfolioDomainRequestStatusViewOnly(DetailView):
|
||||
template_name = "portfolio_domain_request_status_viewonly.html"
|
||||
model = DomainRequest
|
||||
pk_url_kwarg = "domain_request_pk"
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
|
|
@ -155,9 +155,9 @@ def serialize_domain_request(request, domain_request, user):
|
|||
|
||||
# Map the action label to corresponding URLs and icons
|
||||
action_url_map = {
|
||||
"Edit": reverse("edit-domain-request", kwargs={"id": domain_request.id}),
|
||||
"Manage": reverse("domain-request-status", kwargs={"pk": domain_request.id}),
|
||||
"View": reverse("domain-request-status-viewonly", kwargs={"pk": domain_request.id}),
|
||||
"Edit": reverse("edit-domain-request", kwargs={"domain_request_pk": domain_request.id}),
|
||||
"Manage": reverse("domain-request-status", kwargs={"domain_request_pk": domain_request.id}),
|
||||
"View": reverse("domain-request-status-viewonly", kwargs={"domain_request_pk": domain_request.id}),
|
||||
}
|
||||
|
||||
svg_icon_map = {"Edit": "edit", "Manage": "settings", "View": "visibility"}
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.shortcuts import get_object_or_404, redirect, render
|
|||
from django.urls import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.contrib import messages
|
||||
from registrar.decorators import HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM, grant_access
|
||||
from registrar.forms import portfolio as portfolioForms
|
||||
from registrar.models import Portfolio, User
|
||||
from registrar.models.domain import Domain
|
||||
|
@ -25,7 +26,6 @@ from registrar.utility.errors import MissingEmailError
|
|||
from registrar.utility.enums import DefaultUserValues
|
||||
from registrar.views.utility.mixins import PortfolioMemberPermission
|
||||
from registrar.views.utility.permission_views import (
|
||||
PortfolioDomainRequestsPermissionView,
|
||||
PortfolioDomainsPermissionView,
|
||||
PortfolioBasePermissionView,
|
||||
NoPortfolioDomainsPermissionView,
|
||||
|
@ -58,7 +58,8 @@ class PortfolioDomainsView(PortfolioDomainsPermissionView, View):
|
|||
return render(request, "portfolio_domains.html", context)
|
||||
|
||||
|
||||
class PortfolioDomainRequestsView(PortfolioDomainRequestsPermissionView, View):
|
||||
@grant_access(HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM)
|
||||
class PortfolioDomainRequestsView(View):
|
||||
|
||||
template_name = "portfolio_requests.html"
|
||||
|
||||
|
|
|
@ -3,11 +3,7 @@ from .always_404 import always_404
|
|||
|
||||
from .permission_views import (
|
||||
DomainPermissionView,
|
||||
DomainRequestPermissionView,
|
||||
DomainRequestPermissionWithdrawView,
|
||||
DomainRequestWizardPermissionView,
|
||||
PortfolioMembersPermission,
|
||||
DomainRequestPortfolioViewonlyView,
|
||||
DomainInvitationPermissionCancelView,
|
||||
)
|
||||
from .api_views import get_senior_official_from_federal_agency_json
|
||||
|
|
|
@ -286,51 +286,6 @@ class DomainPermission(PermissionsLoginMixin):
|
|||
return True
|
||||
|
||||
|
||||
class DomainRequestPermission(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to domain request if user
|
||||
has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has access to this domain request.
|
||||
|
||||
The user is in self.request.user and the domain needs to be looked
|
||||
up from the domain's primary key in self.kwargs["pk"]
|
||||
"""
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# user needs to be the creator of the domain request
|
||||
# this query is empty if there isn't a domain request with this
|
||||
# id and this user as creator
|
||||
if not DomainRequest.objects.filter(creator=self.request.user, id=self.kwargs["pk"]).exists():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class DomainRequestPortfolioViewonlyPermission(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to domain request if user
|
||||
has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has access to this domain request.
|
||||
|
||||
The user is in self.request.user and the domain needs to be looked
|
||||
up from the domain's primary key in self.kwargs["pk"]
|
||||
"""
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
if not self.request.user.is_org_user(self.request):
|
||||
return False
|
||||
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
if not self.request.user.has_view_all_requests_portfolio_permission(portfolio):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class UserDeleteDomainRolePermission(PermissionsLoginMixin):
|
||||
"""Permission mixin for UserDomainRole if user
|
||||
has access, otherwise 403"""
|
||||
|
@ -365,67 +320,6 @@ class UserDeleteDomainRolePermission(PermissionsLoginMixin):
|
|||
return True
|
||||
|
||||
|
||||
class DomainRequestPermissionWithdraw(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to withdraw action on domain request
|
||||
if user has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has access to withdraw this domain request."""
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# user needs to be the creator of the domain request
|
||||
# this query is empty if there isn't a domain request with this
|
||||
# id and this user as creator
|
||||
if not DomainRequest.objects.filter(creator=self.request.user, id=self.kwargs["pk"]).exists():
|
||||
return False
|
||||
|
||||
# Restricted users should not be able to withdraw domain requests
|
||||
if self.request.user.is_restricted():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class DomainRequestWizardPermission(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to start or edit domain request if
|
||||
user has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has permission to start or edit a domain request.
|
||||
|
||||
The user is in self.request.user
|
||||
"""
|
||||
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# The user has an ineligible flag
|
||||
if self.request.user.is_restricted():
|
||||
return False
|
||||
|
||||
# If the user is an org user and doesn't have add/edit perms, forbid this
|
||||
if self.request.user.is_org_user(self.request):
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
if not self.request.user.has_edit_request_portfolio_permission(portfolio):
|
||||
return False
|
||||
|
||||
# user needs to be the creator of the domain request to edit it.
|
||||
id = self.kwargs.get("id") if hasattr(self, "kwargs") else None
|
||||
if not id:
|
||||
domain_request_wizard = self.request.session.get("wizard_domain_request")
|
||||
if domain_request_wizard:
|
||||
id = domain_request_wizard.get("domain_request_id")
|
||||
|
||||
# If no id is provided, we can assume that the user is starting a new request.
|
||||
# If one IS provided, check that they are the original creator of it.
|
||||
if id:
|
||||
if not DomainRequest.objects.filter(creator=self.request.user, id=id).exists():
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class DomainInvitationPermission(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to domain invitation if user has
|
||||
access, otherwise 403"
|
||||
|
@ -496,23 +390,6 @@ class PortfolioDomainsPermission(PortfolioBasePermission):
|
|||
return super().has_permission()
|
||||
|
||||
|
||||
class PortfolioDomainRequestsPermission(PortfolioBasePermission):
|
||||
"""Permission mixin that allows access to portfolio domain request pages if user
|
||||
has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has access to domain requests 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_any_requests_portfolio_permission(portfolio):
|
||||
return False
|
||||
|
||||
return super().has_permission()
|
||||
|
||||
|
||||
class PortfolioMembersPermission(PortfolioBasePermission):
|
||||
"""Permission mixin that allows access to portfolio members pages if user
|
||||
has access, otherwise 403"""
|
||||
|
|
|
@ -2,18 +2,14 @@
|
|||
|
||||
import abc # abstract base class
|
||||
|
||||
from django.views.generic import DetailView, DeleteView, TemplateView, UpdateView
|
||||
from registrar.models import Domain, DomainRequest, DomainInvitation, Portfolio
|
||||
from django.views.generic import DetailView, DeleteView, UpdateView
|
||||
from registrar.models import Domain, DomainInvitation, Portfolio
|
||||
from registrar.models.user import User
|
||||
from registrar.models.user_domain_role import UserDomainRole
|
||||
|
||||
from .mixins import (
|
||||
DomainPermission,
|
||||
DomainRequestPermission,
|
||||
DomainRequestPermissionWithdraw,
|
||||
DomainInvitationPermission,
|
||||
DomainRequestWizardPermission,
|
||||
PortfolioDomainRequestsPermission,
|
||||
PortfolioDomainsPermission,
|
||||
PortfolioMemberDomainsPermission,
|
||||
PortfolioMemberDomainsEditPermission,
|
||||
|
@ -23,7 +19,6 @@ from .mixins import (
|
|||
PortfolioBasePermission,
|
||||
PortfolioMembersPermission,
|
||||
PortfolioMemberPermission,
|
||||
DomainRequestPortfolioViewonlyPermission,
|
||||
)
|
||||
import logging
|
||||
|
||||
|
@ -86,77 +81,6 @@ class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
class DomainRequestPermissionView(DomainRequestPermission, DetailView, abc.ABC):
|
||||
"""Abstract base view for domain requests that enforces permissions
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
"""
|
||||
|
||||
# DetailView property for what model this is viewing
|
||||
model = DomainRequest
|
||||
# variable name in template context for the model object
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
# Abstract property enforces NotImplementedError on an attribute.
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def template_name(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DomainRequestPortfolioViewonlyView(DomainRequestPortfolioViewonlyPermission, DetailView, abc.ABC):
|
||||
"""Abstract base view for domain requests that enforces permissions
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
"""
|
||||
|
||||
# DetailView property for what model this is viewing
|
||||
model = DomainRequest
|
||||
# variable name in template context for the model object
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
# Abstract property enforces NotImplementedError on an attribute.
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def template_name(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DomainRequestPermissionWithdrawView(DomainRequestPermissionWithdraw, DetailView, abc.ABC):
|
||||
"""Abstract base view for domain request withdraw function
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
"""
|
||||
|
||||
# DetailView property for what model this is viewing
|
||||
model = DomainRequest
|
||||
# variable name in template context for the model object
|
||||
context_object_name = "DomainRequest"
|
||||
|
||||
# Abstract property enforces NotImplementedError on an attribute.
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def template_name(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DomainRequestWizardPermissionView(DomainRequestWizardPermission, TemplateView, abc.ABC):
|
||||
"""Abstract base view for the domain request form that enforces permissions
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
"""
|
||||
|
||||
# Abstract property enforces NotImplementedError on an attribute.
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def template_name(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class DomainInvitationPermissionCancelView(DomainInvitationPermission, UpdateView, abc.ABC):
|
||||
"""Abstract view for cancelling a DomainInvitation."""
|
||||
|
||||
|
@ -164,13 +88,6 @@ class DomainInvitationPermissionCancelView(DomainInvitationPermission, UpdateVie
|
|||
object: DomainInvitation
|
||||
|
||||
|
||||
class DomainRequestPermissionDeleteView(DomainRequestPermission, DeleteView, abc.ABC):
|
||||
"""Abstract view for deleting a DomainRequest."""
|
||||
|
||||
model = DomainRequest
|
||||
object: DomainRequest
|
||||
|
||||
|
||||
class UserDomainRolePermissionDeleteView(UserDeleteDomainRolePermission, DeleteView, abc.ABC):
|
||||
"""Abstract base view for deleting a UserDomainRole.
|
||||
|
||||
|
@ -242,14 +159,6 @@ class NoPortfolioDomainsPermissionView(PortfolioBasePermissionView, abc.ABC):
|
|||
"""
|
||||
|
||||
|
||||
class PortfolioDomainRequestsPermissionView(PortfolioDomainRequestsPermission, PortfolioBasePermissionView, abc.ABC):
|
||||
"""Abstract base view for portfolio domain request views that enforces permissions.
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
"""
|
||||
|
||||
|
||||
class PortfolioMembersPermissionView(PortfolioMembersPermission, PortfolioBasePermissionView, abc.ABC):
|
||||
"""Abstract base view for portfolio members views that enforces permissions.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue