mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-27 04:58:42 +02:00
decorators on domain views
This commit is contained in:
parent
a334f7dc3e
commit
3f2ceb81e8
6 changed files with 90 additions and 19 deletions
|
@ -297,7 +297,11 @@ urlpatterns = [
|
||||||
name="todo",
|
name="todo",
|
||||||
),
|
),
|
||||||
path("domain/<int:domain_pk>", views.DomainView.as_view(), name="domain"),
|
path("domain/<int:domain_pk>", views.DomainView.as_view(), name="domain"),
|
||||||
path("domain/<int:domain_pk>/prototype-dns", views.PrototypeDomainDNSRecordView.as_view(), name="prototype-domain-dns"),
|
path(
|
||||||
|
"domain/<int:domain_pk>/prototype-dns",
|
||||||
|
views.PrototypeDomainDNSRecordView.as_view(),
|
||||||
|
name="prototype-domain-dns",
|
||||||
|
),
|
||||||
path("domain/<int:domain_pk>/users", views.DomainUsersView.as_view(), name="domain-users"),
|
path("domain/<int:domain_pk>/users", views.DomainUsersView.as_view(), name="domain-users"),
|
||||||
path(
|
path(
|
||||||
"domain/<int:domain_pk>/dns",
|
"domain/<int:domain_pk>/dns",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import functools
|
import functools
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from registrar.models import DomainInformation, DomainRequest, UserDomainRole
|
from registrar.models import Domain, DomainInformation, DomainRequest, UserDomainRole
|
||||||
|
|
||||||
# Constants for clarity
|
# Constants for clarity
|
||||||
ALL = "all"
|
ALL = "all"
|
||||||
|
@ -9,6 +9,11 @@ IS_SUPERUSER = "is_superuser"
|
||||||
IS_STAFF = "is_staff"
|
IS_STAFF = "is_staff"
|
||||||
IS_DOMAIN_MANAGER = "is_domain_manager"
|
IS_DOMAIN_MANAGER = "is_domain_manager"
|
||||||
IS_STAFF_MANAGING_DOMAIN = "is_staff_managing_domain"
|
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_DOMAINS_VIEW_MANAGED = "has_portfolio_domains_view_managed"
|
||||||
|
|
||||||
|
|
||||||
def grant_access(*rules):
|
def grant_access(*rules):
|
||||||
"""
|
"""
|
||||||
|
@ -75,19 +80,45 @@ def _user_has_permission(user, request, rules, **kwargs):
|
||||||
conditions_met.append(user.is_superuser)
|
conditions_met.append(user.is_superuser)
|
||||||
|
|
||||||
if not any(conditions_met) and IS_DOMAIN_MANAGER in rules:
|
if not any(conditions_met) and IS_DOMAIN_MANAGER in rules:
|
||||||
domain_id = kwargs.get('domain_pk')
|
domain_id = kwargs.get("domain_pk")
|
||||||
# Check UserDomainRole directly instead of fetching Domain
|
has_permission = _is_domain_manager(user, domain_id)
|
||||||
has_permission = UserDomainRole.objects.filter(user=user, domain_id=domain_id).exists()
|
|
||||||
conditions_met.append(has_permission)
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
if not any(conditions_met) and IS_STAFF_MANAGING_DOMAIN in rules:
|
if not any(conditions_met) and IS_STAFF_MANAGING_DOMAIN in rules:
|
||||||
domain_id = kwargs.get('domain_pk')
|
domain_id = kwargs.get("domain_pk")
|
||||||
has_permission = _can_access_other_user_domains(request, domain_id)
|
has_permission = _can_access_other_user_domains(request, domain_id)
|
||||||
conditions_met.append(has_permission)
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
|
if not any(conditions_met) and HAS_PORTFOLIO_DOMAINS_VIEW_ALL in rules:
|
||||||
|
domain_id = kwargs.get("domain_pk")
|
||||||
|
has_permission = _can_access_domain_via_portfolio_view_all_domains(request, domain_id)
|
||||||
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
|
if not any(conditions_met) and IS_PORTFOLIO_MEMBER_AND_DOMAIN_MANAGER in rules:
|
||||||
|
domain_id = kwargs.get("domain_pk")
|
||||||
|
has_permission = _is_domain_manager(user, domain_id) and _is_portfolio_member(request)
|
||||||
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
|
if not any(conditions_met) and IS_DOMAIN_MANAGER_AND_NOT_PORTFOLIO_MEMBER in rules:
|
||||||
|
domain_id = kwargs.get("domain_pk")
|
||||||
|
has_permission = _is_domain_manager(user, domain_id) and not _is_portfolio_member(request)
|
||||||
|
conditions_met.append(has_permission)
|
||||||
|
|
||||||
return any(conditions_met)
|
return any(conditions_met)
|
||||||
|
|
||||||
|
|
||||||
|
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_portfolio_member(request):
|
||||||
|
"""Checks to see if the user in the request is a member of the
|
||||||
|
portfolio in the request's session."""
|
||||||
|
return request.user.is_org_user(request)
|
||||||
|
|
||||||
|
|
||||||
def _can_access_other_user_domains(request, domain_pk):
|
def _can_access_other_user_domains(request, domain_pk):
|
||||||
"""Checks to see if an authorized user (staff or superuser)
|
"""Checks to see if an authorized user (staff or superuser)
|
||||||
can access a domain that they did not create or were invited to.
|
can access a domain that they did not create or were invited to.
|
||||||
|
@ -144,3 +175,17 @@ def _can_access_other_user_domains(request, domain_pk):
|
||||||
# the user is permissioned,
|
# the user is permissioned,
|
||||||
# and it is in a valid status
|
# and it is in a valid status
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _can_access_domain_via_portfolio_view_all_domains(request, domain_pk):
|
||||||
|
"""Returns whether the user in the request can access the domain
|
||||||
|
via portfolio view all domains permission."""
|
||||||
|
# NOTE: determine if in practice this ever needs to be called on its own
|
||||||
|
# or if it can be combined with view_managed_domains
|
||||||
|
portfolio = request.session.get("portfolio")
|
||||||
|
if request.user.has_view_all_domains_portfolio_permission(portfolio):
|
||||||
|
if Domain.objects.filter(id=domain_pk).exists():
|
||||||
|
domain = Domain.objects.get(id=domain_pk)
|
||||||
|
if domain.domain_info.portfolio == portfolio:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
@ -177,7 +177,7 @@ class CheckPortfolioMiddleware:
|
||||||
|
|
||||||
|
|
||||||
class RestrictAccessMiddleware:
|
class RestrictAccessMiddleware:
|
||||||
""" Middleware that blocks all views unless explicitly permitted """
|
"""Middleware that blocks all views unless explicitly permitted"""
|
||||||
|
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
|
|
@ -15,7 +15,14 @@ from django.shortcuts import redirect, render, get_object_or_404
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.views.generic.edit import FormMixin
|
from django.views.generic.edit import FormMixin
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from registrar.decorators import IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN, grant_access
|
from registrar.decorators import (
|
||||||
|
HAS_PORTFOLIO_DOMAINS_VIEW_ALL,
|
||||||
|
IS_DOMAIN_MANAGER,
|
||||||
|
IS_DOMAIN_MANAGER_AND_NOT_PORTFOLIO_MEMBER,
|
||||||
|
IS_PORTFOLIO_MEMBER_AND_DOMAIN_MANAGER,
|
||||||
|
IS_STAFF_MANAGING_DOMAIN,
|
||||||
|
grant_access,
|
||||||
|
)
|
||||||
from registrar.forms.domain import DomainSuborganizationForm, DomainRenewalForm
|
from registrar.forms.domain import DomainSuborganizationForm, DomainRenewalForm
|
||||||
from registrar.models import (
|
from registrar.models import (
|
||||||
Domain,
|
Domain,
|
||||||
|
@ -257,7 +264,8 @@ class DomainFormBaseView(DomainBaseView, FormMixin):
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN, HAS_PORTFOLIO_DOMAINS_VIEW_ALL)
|
||||||
class DomainView(DomainBaseView):
|
class DomainView(DomainBaseView):
|
||||||
"""Domain detail overview page."""
|
"""Domain detail overview page."""
|
||||||
|
|
||||||
|
@ -311,6 +319,7 @@ class DomainView(DomainBaseView):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
self._update_session_with_domain()
|
self._update_session_with_domain()
|
||||||
|
|
||||||
|
|
||||||
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainRenewalView(DomainBaseView):
|
class DomainRenewalView(DomainBaseView):
|
||||||
"""Domain detail overview page."""
|
"""Domain detail overview page."""
|
||||||
|
@ -380,6 +389,7 @@ class DomainRenewalView(DomainBaseView):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainOrgNameAddressView(DomainFormBaseView):
|
class DomainOrgNameAddressView(DomainFormBaseView):
|
||||||
"""Organization view"""
|
"""Organization view"""
|
||||||
|
@ -422,6 +432,7 @@ class DomainOrgNameAddressView(DomainFormBaseView):
|
||||||
return super().has_permission()
|
return super().has_permission()
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_PORTFOLIO_MEMBER_AND_DOMAIN_MANAGER)
|
||||||
class DomainSubOrganizationView(DomainFormBaseView):
|
class DomainSubOrganizationView(DomainFormBaseView):
|
||||||
"""Suborganization view"""
|
"""Suborganization view"""
|
||||||
|
|
||||||
|
@ -468,6 +479,7 @@ class DomainSubOrganizationView(DomainFormBaseView):
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER_AND_NOT_PORTFOLIO_MEMBER)
|
||||||
class DomainSeniorOfficialView(DomainFormBaseView):
|
class DomainSeniorOfficialView(DomainFormBaseView):
|
||||||
"""Domain senior official editing view."""
|
"""Domain senior official editing view."""
|
||||||
|
|
||||||
|
@ -525,6 +537,7 @@ class DomainSeniorOfficialView(DomainFormBaseView):
|
||||||
return super().has_permission()
|
return super().has_permission()
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainDNSView(DomainBaseView):
|
class DomainDNSView(DomainBaseView):
|
||||||
"""DNS Information View."""
|
"""DNS Information View."""
|
||||||
|
|
||||||
|
@ -741,6 +754,7 @@ class PrototypeDomainDNSRecordView(DomainFormBaseView):
|
||||||
return super().post(request)
|
return super().post(request)
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainNameserversView(DomainFormBaseView):
|
class DomainNameserversView(DomainFormBaseView):
|
||||||
"""Domain nameserver editing view."""
|
"""Domain nameserver editing view."""
|
||||||
|
|
||||||
|
@ -868,6 +882,7 @@ class DomainNameserversView(DomainFormBaseView):
|
||||||
return super().form_valid(formset)
|
return super().form_valid(formset)
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainDNSSECView(DomainFormBaseView):
|
class DomainDNSSECView(DomainFormBaseView):
|
||||||
"""Domain DNSSEC editing view."""
|
"""Domain DNSSEC editing view."""
|
||||||
|
|
||||||
|
@ -905,6 +920,7 @@ class DomainDNSSECView(DomainFormBaseView):
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainDsDataView(DomainFormBaseView):
|
class DomainDsDataView(DomainFormBaseView):
|
||||||
"""Domain DNSSEC ds data editing view."""
|
"""Domain DNSSEC ds data editing view."""
|
||||||
|
|
||||||
|
@ -1023,6 +1039,7 @@ class DomainDsDataView(DomainFormBaseView):
|
||||||
return super().form_valid(formset)
|
return super().form_valid(formset)
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainSecurityEmailView(DomainFormBaseView):
|
class DomainSecurityEmailView(DomainFormBaseView):
|
||||||
"""Domain security email editing view."""
|
"""Domain security email editing view."""
|
||||||
|
|
||||||
|
@ -1094,6 +1111,7 @@ class DomainSecurityEmailView(DomainFormBaseView):
|
||||||
return redirect(self.get_success_url())
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainUsersView(DomainBaseView):
|
class DomainUsersView(DomainBaseView):
|
||||||
"""Domain managers page in the domain details."""
|
"""Domain managers page in the domain details."""
|
||||||
|
|
||||||
|
@ -1189,6 +1207,7 @@ class DomainUsersView(DomainBaseView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainAddUserView(DomainFormBaseView):
|
class DomainAddUserView(DomainFormBaseView):
|
||||||
"""Inside of a domain's user management, a form for adding users.
|
"""Inside of a domain's user management, a form for adding users.
|
||||||
|
|
||||||
|
@ -1286,6 +1305,7 @@ class DomainAddUserView(DomainFormBaseView):
|
||||||
messages.success(self.request, f"Added user {email}.")
|
messages.success(self.request, f"Added user {email}.")
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainInvitationCancelView(SuccessMessageMixin, DomainInvitationPermissionCancelView):
|
class DomainInvitationCancelView(SuccessMessageMixin, DomainInvitationPermissionCancelView):
|
||||||
object: DomainInvitation
|
object: DomainInvitation
|
||||||
fields = []
|
fields = []
|
||||||
|
@ -1311,6 +1331,7 @@ class DomainInvitationCancelView(SuccessMessageMixin, DomainInvitationPermission
|
||||||
return f"Canceled invitation to {self.object.email}."
|
return f"Canceled invitation to {self.object.email}."
|
||||||
|
|
||||||
|
|
||||||
|
@grant_access(IS_DOMAIN_MANAGER, IS_STAFF_MANAGING_DOMAIN)
|
||||||
class DomainDeleteUserView(UserDomainRolePermissionDeleteView):
|
class DomainDeleteUserView(UserDomainRolePermissionDeleteView):
|
||||||
"""Inside of a domain's user management, a form for deleting users."""
|
"""Inside of a domain's user management, a form for deleting users."""
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from django.shortcuts import render
|
||||||
|
|
||||||
from registrar.decorators import grant_access, ALL
|
from registrar.decorators import grant_access, ALL
|
||||||
|
|
||||||
|
|
||||||
@grant_access(ALL)
|
@grant_access(ALL)
|
||||||
def index(request):
|
def index(request):
|
||||||
"""This page is available to anyone without logging in."""
|
"""This page is available to anyone without logging in."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue