mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-16 17:47:02 +02:00
Merge remote-tracking branch 'origin/main' into rjm/811-approved-rejected-approved
This commit is contained in:
commit
d859a8be03
13 changed files with 364 additions and 29 deletions
|
@ -176,8 +176,9 @@ class DomainAdmin(ListHeaderAdmin):
|
|||
readonly_fields = ["state"]
|
||||
|
||||
def response_change(self, request, obj):
|
||||
ACTION_BUTTON = "_place_client_hold"
|
||||
if ACTION_BUTTON in request.POST:
|
||||
PLACE_HOLD = "_place_client_hold"
|
||||
EDIT_DOMAIN = "_edit_domain"
|
||||
if PLACE_HOLD in request.POST:
|
||||
try:
|
||||
obj.place_client_hold()
|
||||
except Exception as err:
|
||||
|
@ -192,9 +193,30 @@ class DomainAdmin(ListHeaderAdmin):
|
|||
% obj.name,
|
||||
)
|
||||
return HttpResponseRedirect(".")
|
||||
|
||||
elif EDIT_DOMAIN in request.POST:
|
||||
# We want to know, globally, when an edit action occurs
|
||||
request.session["analyst_action"] = "edit"
|
||||
# Restricts this action to this domain (pk) only
|
||||
request.session["analyst_action_location"] = obj.id
|
||||
return HttpResponseRedirect(reverse("domain", args=(obj.id,)))
|
||||
return super().response_change(request, obj)
|
||||
|
||||
def change_view(self, request, object_id):
|
||||
# If the analyst was recently editing a domain page,
|
||||
# delete any associated session values
|
||||
if "analyst_action" in request.session:
|
||||
del request.session["analyst_action"]
|
||||
del request.session["analyst_action_location"]
|
||||
return super().change_view(request, object_id)
|
||||
|
||||
def has_change_permission(self, request, obj=None):
|
||||
# Fixes a bug wherein users which are only is_staff
|
||||
# can access 'change' when GET,
|
||||
# but cannot access this page when it is a request of type POST.
|
||||
if request.user.is_staff:
|
||||
return True
|
||||
return super().has_change_permission(request, obj)
|
||||
|
||||
|
||||
class ContactAdmin(ListHeaderAdmin):
|
||||
"""Custom contact admin class to add search."""
|
||||
|
|
50
src/registrar/assets/js/get-gov-admin.js
Normal file
50
src/registrar/assets/js/get-gov-admin.js
Normal file
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* @file get-gov-admin.js includes custom code for the .gov registrar admin portal.
|
||||
*
|
||||
* Constants and helper functions are at the top.
|
||||
* Event handlers are in the middle.
|
||||
* Initialization (run-on-load) stuff goes at the bottom.
|
||||
*/
|
||||
|
||||
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
|
||||
// Helper functions.
|
||||
/** Either sets attribute target="_blank" to a given element, or removes it */
|
||||
function openInNewTab(el, removeAttribute = false){
|
||||
if(removeAttribute){
|
||||
el.setAttribute("target", "_blank");
|
||||
}else{
|
||||
el.removeAttribute("target", "_blank");
|
||||
}
|
||||
};
|
||||
|
||||
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
|
||||
// Event handlers.
|
||||
|
||||
// <<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
|
||||
// Initialization code.
|
||||
|
||||
/** An IIFE for pages in DjangoAdmin which may need custom JS implementation.
|
||||
* Currently only appends target="_blank" to the domain_form object,
|
||||
* but this can be expanded.
|
||||
*/
|
||||
(function (){
|
||||
/*
|
||||
On mouseover, appends target="_blank" on domain_form under the Domain page.
|
||||
The reason for this is that the template has a form that contains multiple buttons.
|
||||
The structure of that template complicates seperating those buttons
|
||||
out of the form (while maintaining the same position on the page).
|
||||
However, if we want to open one of those submit actions to a new tab -
|
||||
such as the manage domain button - we need to dynamically append target.
|
||||
As there is no built-in django method which handles this, we do it here.
|
||||
*/
|
||||
function prepareDjangoAdmin() {
|
||||
let domainFormElement = document.getElementById("domain_form");
|
||||
let domainSubmitButton = document.getElementById("manageDomainSubmitButton");
|
||||
if(domainSubmitButton && domainFormElement){
|
||||
domainSubmitButton.addEventListener("mouseover", () => openInNewTab(domainFormElement, true));
|
||||
domainSubmitButton.addEventListener("mouseout", () => openInNewTab(domainFormElement, false));
|
||||
}
|
||||
}
|
||||
|
||||
prepareDjangoAdmin();
|
||||
})();
|
|
@ -432,3 +432,21 @@ abbr[title] {
|
|||
height: units('mobile');
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes some font size disparities with the Figma
|
||||
// for usa-alert alert elements
|
||||
.usa-alert {
|
||||
.usa-alert__heading.larger-font-sizing {
|
||||
font-size: units(3);
|
||||
}
|
||||
}
|
||||
|
||||
// The icon was off center for some reason
|
||||
// Fixes that issue
|
||||
@media (min-width: 64em){
|
||||
.usa-alert--warning{
|
||||
.usa-alert__body::before {
|
||||
left: 1rem !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ class UserFixture:
|
|||
"last_name": "Adkinson",
|
||||
},
|
||||
{
|
||||
"username": "bb21f687-c773-4df3-9243-111cfd4c0be4",
|
||||
"username": "2bf518c2-485a-4c42-ab1a-f5a8b0a08484",
|
||||
"first_name": "Paul",
|
||||
"last_name": "Kuykendall",
|
||||
},
|
||||
|
|
|
@ -60,12 +60,11 @@ Load our custom filters to extract info from the django generated markup.
|
|||
<tr><td colspan="{{ result|length }}">{{ result.form.non_field_errors }}</td></tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
|
||||
{% with result_value=result.0|extract_value %}
|
||||
{% with result_label=result.1|extract_a_text %}
|
||||
<td>
|
||||
<input type="checkbox" name="_selected_action" value="{{ result_value|default:'value' }}" id="{{ result_label|default:result_value }}" class="action-select">
|
||||
<label class="usa-sr-only" for="{{ result_label|default:result_value }}">{{ result_label|default:'label' }}</label>
|
||||
<input type="checkbox" name="_selected_action" value="{{ result_value|default:'value' }}" id="{{ result_value|default:'value' }}-{{ result_label|default:'label' }}" class="action-select">
|
||||
<label class="usa-sr-only" for="{{ result_value|default:'value' }}-{{ result_label|default:'label' }}">{{ result_label|default:'label' }}</label>
|
||||
</td>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
{% extends 'admin/change_form.html' %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
<script type="application/javascript" src="{% static 'js/get-gov-admin.js' %}" defer></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block field_sets %}
|
||||
<div class="submit-row">
|
||||
<input id="manageDomainSubmitButton" type="submit" value="Manage Domain" name="_edit_domain">
|
||||
<input type="submit" value="Place hold" name="_place_client_hold">
|
||||
</div>
|
||||
{{ block.super }}
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
{% block content %}
|
||||
<div class="grid-container">
|
||||
<div class="grid-row">
|
||||
{% if not is_analyst_or_superuser or not analyst_action or analyst_action_location != domain.pk %}
|
||||
<p class="font-body-md margin-top-0 margin-bottom-2
|
||||
text-primary-darker text-semibold"
|
||||
>
|
||||
<span class="usa-sr-only"> Domain name:</span> {{ domain.name }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid-row grid-gap">
|
||||
<div class="tablet:grid-col-3">
|
||||
|
@ -20,15 +22,26 @@
|
|||
<div class="tablet:grid-col-9">
|
||||
<main id="main-content" class="grid-container">
|
||||
|
||||
{% if is_analyst_or_superuser and analyst_action == 'edit' and analyst_action_location == domain.pk %}
|
||||
<div class="usa-alert usa-alert--warning margin-bottom-2">
|
||||
<div class="usa-alert__body">
|
||||
<h4 class="usa-alert__heading larger-font-sizing">Attention!</h4>
|
||||
<p class="usa-alert__text ">
|
||||
You are making changes to a registrant’s domain. When finished making changes, close this tab and inform the registrant of your updates.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<a href="{% url 'home' %}" class="breadcrumb__back">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
|
||||
<use xlink:href="{% static 'img/sprite.svg' %}#arrow_back"></use>
|
||||
</svg>
|
||||
|
||||
<p class="margin-left-05 margin-top-0 margin-bottom-0 line-height-sans-1">
|
||||
Back to manage your domains
|
||||
</p>
|
||||
</a>
|
||||
|
||||
{% endif %}
|
||||
{# messages block is under the back breadcrumb link #}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
<h1>Domain contact information</h1>
|
||||
|
||||
<p>If you’d like us to use a different name, email, or phone number you can make those changes below. Changing your contact information here won’t affect your Login.gov account information.</p>
|
||||
<p>If you’d like us to use a different name, email, or phone number you can make those changes below. <strong>Updating your contact information here will update the contact information for all domains in your account.</strong> However, it won’t affect your Login.gov account information.
|
||||
</p>
|
||||
|
||||
{% include "includes/required_fields.html" %}
|
||||
|
||||
|
|
|
@ -518,3 +518,11 @@ def multiple_unalphabetical_domain_objects(
|
|||
application = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
applications.append(application)
|
||||
return applications
|
||||
|
||||
|
||||
def generic_domain_object(domain_type, object_name):
|
||||
"""Returns a generic domain object of
|
||||
domain_type 'application', 'information', or 'invitation'"""
|
||||
mock = AuditedAdminMockData()
|
||||
application = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
return application
|
||||
|
|
|
@ -2,8 +2,10 @@ from django.test import TestCase, RequestFactory, Client
|
|||
from django.contrib.admin.sites import AdminSite
|
||||
from contextlib import ExitStack
|
||||
from django.contrib import messages
|
||||
from django.urls import reverse
|
||||
|
||||
from registrar.admin import (
|
||||
DomainAdmin,
|
||||
DomainApplicationAdmin,
|
||||
ListHeaderAdmin,
|
||||
MyUserAdmin,
|
||||
|
@ -15,15 +17,17 @@ from registrar.models import (
|
|||
Domain,
|
||||
User,
|
||||
DomainInvitation,
|
||||
Domain,
|
||||
)
|
||||
from .common import (
|
||||
completed_application,
|
||||
generic_domain_object,
|
||||
mock_user,
|
||||
create_superuser,
|
||||
create_user,
|
||||
multiple_unalphabetical_domain_objects,
|
||||
)
|
||||
|
||||
from django.contrib.sessions.backends.db import SessionStore
|
||||
from django.contrib.auth import get_user_model
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -928,3 +932,129 @@ class AuditedAdminTest(TestCase):
|
|||
DomainInformation.objects.all().delete()
|
||||
DomainApplication.objects.all().delete()
|
||||
DomainInvitation.objects.all().delete()
|
||||
|
||||
|
||||
class DomainSessionVariableTest(TestCase):
|
||||
"""Test cases for session variables in Django Admin"""
|
||||
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
self.admin = DomainAdmin(Domain, None)
|
||||
self.client = Client(HTTP_HOST="localhost:8080")
|
||||
|
||||
def test_session_vars_set_correctly(self):
|
||||
"""Checks if session variables are being set correctly"""
|
||||
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
dummy_domain_information = generic_domain_object("information", "session")
|
||||
request = self.get_factory_post_edit_domain(dummy_domain_information.domain.pk)
|
||||
self.populate_session_values(request, dummy_domain_information.domain)
|
||||
self.assertEqual(request.session["analyst_action"], "edit")
|
||||
self.assertEqual(
|
||||
request.session["analyst_action_location"],
|
||||
dummy_domain_information.domain.pk,
|
||||
)
|
||||
|
||||
def test_session_vars_set_correctly_hardcoded_domain(self):
|
||||
"""Checks if session variables are being set correctly"""
|
||||
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
dummy_domain_information: Domain = generic_domain_object(
|
||||
"information", "session"
|
||||
)
|
||||
dummy_domain_information.domain.pk = 1
|
||||
|
||||
request = self.get_factory_post_edit_domain(dummy_domain_information.domain.pk)
|
||||
self.populate_session_values(request, dummy_domain_information.domain)
|
||||
self.assertEqual(request.session["analyst_action"], "edit")
|
||||
self.assertEqual(request.session["analyst_action_location"], 1)
|
||||
|
||||
def test_session_variables_reset_correctly(self):
|
||||
"""Checks if incorrect session variables get overridden"""
|
||||
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
dummy_domain_information = generic_domain_object("information", "session")
|
||||
request = self.get_factory_post_edit_domain(dummy_domain_information.domain.pk)
|
||||
|
||||
self.populate_session_values(
|
||||
request, dummy_domain_information.domain, preload_bad_data=True
|
||||
)
|
||||
|
||||
self.assertEqual(request.session["analyst_action"], "edit")
|
||||
self.assertEqual(
|
||||
request.session["analyst_action_location"],
|
||||
dummy_domain_information.domain.pk,
|
||||
)
|
||||
|
||||
def test_session_variables_retain_information(self):
|
||||
"""Checks to see if session variables retain old information"""
|
||||
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
dummy_domain_information_list = multiple_unalphabetical_domain_objects(
|
||||
"information"
|
||||
)
|
||||
for item in dummy_domain_information_list:
|
||||
request = self.get_factory_post_edit_domain(item.domain.pk)
|
||||
self.populate_session_values(request, item.domain)
|
||||
|
||||
self.assertEqual(request.session["analyst_action"], "edit")
|
||||
self.assertEqual(request.session["analyst_action_location"], item.domain.pk)
|
||||
|
||||
def test_session_variables_concurrent_requests(self):
|
||||
"""Simulates two requests at once"""
|
||||
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
info_first = generic_domain_object("information", "session")
|
||||
info_second = generic_domain_object("information", "session2")
|
||||
|
||||
request_first = self.get_factory_post_edit_domain(info_first.domain.pk)
|
||||
request_second = self.get_factory_post_edit_domain(info_second.domain.pk)
|
||||
|
||||
self.populate_session_values(request_first, info_first.domain, True)
|
||||
self.populate_session_values(request_second, info_second.domain, True)
|
||||
|
||||
# Check if anything got nulled out
|
||||
self.assertNotEqual(request_first.session["analyst_action"], None)
|
||||
self.assertNotEqual(request_second.session["analyst_action"], None)
|
||||
self.assertNotEqual(request_first.session["analyst_action_location"], None)
|
||||
self.assertNotEqual(request_second.session["analyst_action_location"], None)
|
||||
|
||||
# Check if they are both the same action 'type'
|
||||
self.assertEqual(request_first.session["analyst_action"], "edit")
|
||||
self.assertEqual(request_second.session["analyst_action"], "edit")
|
||||
|
||||
# Check their locations, and ensure they aren't the same across both
|
||||
self.assertNotEqual(
|
||||
request_first.session["analyst_action_location"],
|
||||
request_second.session["analyst_action_location"],
|
||||
)
|
||||
|
||||
def populate_session_values(self, request, domain_object, preload_bad_data=False):
|
||||
"""Boilerplate for creating mock sessions"""
|
||||
request.user = self.client
|
||||
request.session = SessionStore()
|
||||
request.session.create()
|
||||
if preload_bad_data:
|
||||
request.session["analyst_action"] = "invalid"
|
||||
request.session["analyst_action_location"] = "bad location"
|
||||
self.admin.response_change(request, domain_object)
|
||||
|
||||
def get_factory_post_edit_domain(self, primary_key):
|
||||
"""Posts to registrar domain change
|
||||
with the edit domain button 'clicked',
|
||||
then returns the factory object"""
|
||||
return self.factory.post(
|
||||
reverse("admin:registrar_domain_change", args=(primary_key,)),
|
||||
{"_edit_domain": "true"},
|
||||
follow=True,
|
||||
)
|
||||
|
|
|
@ -79,6 +79,7 @@ class DomainOrgNameAddressView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, "The organization name and mailing address has been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_valid(form)
|
||||
|
||||
|
@ -121,6 +122,7 @@ class DomainAuthorizingOfficialView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, "The authorizing official for this domain has been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_valid(form)
|
||||
|
||||
|
@ -187,6 +189,7 @@ class DomainNameserversView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, "The name servers for this domain have been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_valid(formset)
|
||||
|
||||
|
@ -227,6 +230,7 @@ class DomainYourContactInformationView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, "Your contact information for this domain has been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_valid(form)
|
||||
|
||||
|
@ -272,6 +276,7 @@ class DomainSecurityEmailView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, "The security email for this domain have been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
|
@ -347,6 +352,7 @@ class DomainAddUserView(DomainPermissionView, FormMixin):
|
|||
messages.success(
|
||||
self.request, f"Invited {email_address} to this domain."
|
||||
)
|
||||
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
def form_valid(self, form):
|
||||
|
@ -368,6 +374,7 @@ class DomainAddUserView(DomainPermissionView, FormMixin):
|
|||
pass
|
||||
|
||||
messages.success(self.request, f"Added user {requested_email}.")
|
||||
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,16 @@
|
|||
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
|
||||
from registrar.models import UserDomainRole, DomainApplication, DomainInvitation
|
||||
from registrar.models import (
|
||||
DomainApplication,
|
||||
DomainInvitation,
|
||||
DomainInformation,
|
||||
UserDomainRole,
|
||||
)
|
||||
import logging
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PermissionsLoginMixin(PermissionRequiredMixin):
|
||||
|
@ -25,27 +34,80 @@ class DomainPermission(PermissionsLoginMixin):
|
|||
up from the domain's primary key in self.kwargs["pk"]
|
||||
"""
|
||||
|
||||
# ticket 806
|
||||
# if self.request.user is staff or admin and
|
||||
# domain.application__status = 'approved' or 'rejected' or 'action needed'
|
||||
# return True
|
||||
|
||||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# user needs to have a role on the domain
|
||||
if not UserDomainRole.objects.filter(
|
||||
user=self.request.user, domain__id=self.kwargs["pk"]
|
||||
).exists():
|
||||
return False
|
||||
|
||||
# The user has an ineligible flag
|
||||
if self.request.user.is_restricted():
|
||||
return False
|
||||
|
||||
pk = self.kwargs["pk"]
|
||||
# If pk is none then something went very wrong...
|
||||
if pk is None:
|
||||
raise ValueError("Primary key is None")
|
||||
|
||||
if self.can_access_other_user_domains(pk):
|
||||
return True
|
||||
|
||||
# user needs to have a role on the domain
|
||||
if not UserDomainRole.objects.filter(
|
||||
user=self.request.user, domain__id=pk
|
||||
).exists():
|
||||
return False
|
||||
|
||||
# if we need to check more about the nature of role, do it here.
|
||||
return True
|
||||
|
||||
def can_access_other_user_domains(self, pk):
|
||||
"""Checks to see if an authorized user (staff or superuser)
|
||||
can access a domain that they did not create or was invited to.
|
||||
"""
|
||||
|
||||
# Check if the user is permissioned...
|
||||
user_is_analyst_or_superuser = (
|
||||
self.request.user.is_staff or self.request.user.is_superuser
|
||||
)
|
||||
|
||||
if not user_is_analyst_or_superuser:
|
||||
return False
|
||||
|
||||
# Check if the user is attempting a valid edit action.
|
||||
# In other words, if the analyst/admin did not click
|
||||
# the 'Manage Domain' button in /admin,
|
||||
# then they cannot access this page.
|
||||
session = self.request.session
|
||||
can_do_action = (
|
||||
"analyst_action" in session
|
||||
and "analyst_action_location" in session
|
||||
and session["analyst_action_location"] == pk
|
||||
)
|
||||
|
||||
if not can_do_action:
|
||||
return False
|
||||
|
||||
# Analysts may manage domains, when they are in these statuses:
|
||||
valid_domain_statuses = [
|
||||
DomainApplication.APPROVED,
|
||||
DomainApplication.IN_REVIEW,
|
||||
DomainApplication.REJECTED,
|
||||
DomainApplication.ACTION_NEEDED,
|
||||
# Edge case - some domains do not have
|
||||
# a status or DomainInformation... aka a status of 'None'.
|
||||
# It is necessary to access those to correct errors.
|
||||
None,
|
||||
]
|
||||
|
||||
requested_domain = None
|
||||
if DomainInformation.objects.filter(id=pk).exists():
|
||||
requested_domain = DomainInformation.objects.get(id=pk)
|
||||
|
||||
if requested_domain.domain_application.status not in valid_domain_statuses:
|
||||
return False
|
||||
|
||||
# Valid session keys exist,
|
||||
# the user is permissioned,
|
||||
# and it is in a valid status
|
||||
return True
|
||||
|
||||
|
||||
class DomainApplicationPermission(PermissionsLoginMixin):
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import abc # abstract base class
|
||||
|
||||
from django.views.generic import DetailView, DeleteView, TemplateView
|
||||
|
||||
from registrar.models import Domain, DomainApplication, DomainInvitation
|
||||
|
||||
from .mixins import (
|
||||
|
@ -12,6 +11,9 @@ from .mixins import (
|
|||
DomainInvitationPermission,
|
||||
ApplicationWizardPermission,
|
||||
)
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
|
||||
|
@ -27,6 +29,22 @@ class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
|
|||
# variable name in template context for the model object
|
||||
context_object_name = "domain"
|
||||
|
||||
# Adds context information for user permissions
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
user = self.request.user
|
||||
context["is_analyst_or_superuser"] = user.is_staff or user.is_superuser
|
||||
# Stored in a variable for the linter
|
||||
action = "analyst_action"
|
||||
action_location = "analyst_action_location"
|
||||
# Flag to see if an analyst is attempting to make edits
|
||||
if action in self.request.session:
|
||||
context[action] = self.request.session[action]
|
||||
if action_location in self.request.session:
|
||||
context[action_location] = self.request.session[action_location]
|
||||
|
||||
return context
|
||||
|
||||
# Abstract property enforces NotImplementedError on an attribute.
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue