Redirect and basic changes

This commit is contained in:
zandercymatics 2023-08-18 15:29:03 -06:00
parent 87bb71a214
commit bd0edf7203
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
9 changed files with 124 additions and 44 deletions

View file

@ -160,6 +160,17 @@ class DomainAdmin(ListHeaderAdmin):
return super().response_change(request, obj) return super().response_change(request, obj)
# Sets domain_id as a context var
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["domain_id"] = object_id
return super().change_view(
request,
object_id,
form_url,
extra_context=extra_context,
)
class ContactAdmin(ListHeaderAdmin): class ContactAdmin(ListHeaderAdmin):

View file

@ -1,7 +1,7 @@
@use "cisa_colors" as *; @use "cisa_colors" as *;
@use "uswds-core" as *; @use "uswds-core" as *;
// We'll use Django's CSS vars: https://docs.djangoproject.com/en/4.2/ref/contrib/admin/#theming-support // We'll use Django's CSS vars: https://docs.djangoproject.com/en/4.2/ref/contrib/admin/#theming-support
// and assign USWDS theme vars whenever possible // and assign USWDS theme vars whenever possible
// If needed (see below), we'll use the USWDS hex value // If needed (see below), we'll use the USWDS hex value
// As a last resort, we'll use CISA colors to supplement the palette // As a last resort, we'll use CISA colors to supplement the palette
@ -72,34 +72,34 @@ html[data-theme="light"] {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:root, :root,
html[data-theme="dark"] { html[data-theme="dark"] {
// Edit the primary to meet accessibility requ. // Edit the primary to meet accessibility requ.
--primary: #23485a; --primary: #23485a;
--primary-fg: #f7f7f7; --primary-fg: #f7f7f7;
--body-fg: #eeeeee; --body-fg: #eeeeee;
--body-bg: #121212; --body-bg: #121212;
--body-quiet-color: #e0e0e0; --body-quiet-color: #e0e0e0;
--body-loud-color: #ffffff; --body-loud-color: #ffffff;
--breadcrumbs-link-fg: #e0e0e0; --breadcrumbs-link-fg: #e0e0e0;
--breadcrumbs-bg: var(--primary); --breadcrumbs-bg: var(--primary);
--link-fg: #81d4fa; --link-fg: #81d4fa;
--link-hover-color: #4ac1f7; --link-hover-color: #4ac1f7;
--link-selected-fg: #6f94c6; --link-selected-fg: #6f94c6;
--hairline-color: #272727; --hairline-color: #272727;
--border-color: #353535; --border-color: #353535;
--error-fg: #e35f5f; --error-fg: #e35f5f;
--message-success-bg: #006b1b; --message-success-bg: #006b1b;
--message-warning-bg: #583305; --message-warning-bg: #583305;
--message-error-bg: #570808; --message-error-bg: #570808;
--darkened-bg: #212121; --darkened-bg: #212121;
--selected-bg: #1b1b1b; --selected-bg: #1b1b1b;
--selected-row: #00363a; --selected-row: #00363a;
--close-button-bg: #333333; --close-button-bg: #333333;
--close-button-hover-bg: #666666; --close-button-hover-bg: #666666;
} }
@ -108,7 +108,7 @@ html[data-theme="light"] {
.change-list .usa-table, .change-list .usa-table,
.change-list .usa-table--striped tbody tr:nth-child(odd) td, .change-list .usa-table--striped tbody tr:nth-child(odd) td,
.change-list .usa-table--borderless thead th, .change-list .usa-table--borderless thead th,
.change-list .usa-table thead td, .change-list .usa-table thead td,
.change-list .usa-table thead th, .change-list .usa-table thead th,
body.dashboard, body.dashboard,
body.change-list, body.change-list,
@ -122,7 +122,7 @@ html[data-theme="dark"] {
.change-list .usa-table, .change-list .usa-table,
.change-list .usa-table--striped tbody tr:nth-child(odd) td, .change-list .usa-table--striped tbody tr:nth-child(odd) td,
.change-list .usa-table--borderless thead th, .change-list .usa-table--borderless thead th,
.change-list .usa-table thead td, .change-list .usa-table thead td,
.change-list .usa-table thead th, .change-list .usa-table thead th,
body.dashboard, body.dashboard,
body.change-list, body.change-list,
@ -163,10 +163,31 @@ table > caption > a {
height: auto!important; height: auto!important;
} }
// Keep th from collapsing // Keep th from collapsing
.min-width-25 { .min-width-25 {
min-width: 25px; min-width: 25px;
} }
.min-width-81 { .min-width-81 {
min-width: 81px; min-width: 81px;
} }
.buttonAdminPadding {
background: var(--button-bg);
padding: 10px 15px;
border: none;
border-radius: 4px;
color: var(--button-fg);
cursor: pointer;
transition: background 0.15s;
}
.submit-row input {
height: 2.1875rem;
line-height: 0.9375rem;
}
a.button{
font-size: 100% !important;
padding: 9px 15px !important;
}

View file

@ -2,6 +2,7 @@
{% block field_sets %} {% block field_sets %}
<div class="submit-row"> <div class="submit-row">
<a href="{% url 'domain' domain_id %}" class="button" >Edit domain</a>
<input type="submit" value="Place hold" name="_place_client_hold"> <input type="submit" value="Place hold" name="_place_client_hold">
</div> </div>
{{ block.super }} {{ block.super }}

View file

@ -5,11 +5,11 @@
{% block content %} {% block content %}
<div class="grid-container"> <div class="grid-container">
<div class="grid-row"> <div class="grid-row">
<p class="font-body-md margin-top-0 margin-bottom-2 <p class="font-body-md margin-top-0 margin-bottom-2
text-primary-darker text-semibold" text-primary-darker text-semibold"
> >
<span class="usa-sr-only"> Domain name:</span> {{ domain.name }} <span class="usa-sr-only"> Domain name:</span> {{ domain.name }}
</p> </p>
</div> </div>
<div class="grid-row grid-gap"> <div class="grid-row grid-gap">
@ -19,16 +19,29 @@
<div class="tablet:grid-col-9"> <div class="tablet:grid-col-9">
<main id="main-content" class="grid-container"> <main id="main-content" class="grid-container">
{% if not is_analyst_or_superuser %}
<a href="{% url 'home' %}" class="breadcrumb__back"> <a href="{% url 'home' %}" class="breadcrumb__back">
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img"> <svg class="usa-icon" aria-hidden="true" focusable="false" role="img">
<use xlink:href="{% static 'img/sprite.svg' %}#arrow_back"></use> <use xlink:href="{% static 'img/sprite.svg' %}#arrow_back"></use>
</svg> </svg>
<p class="margin-left-05 margin-top-0 margin-bottom-0 line-height-sans-1">
Back to manage your domains
</p>
</a>
<p class="margin-left-05 margin-top-0 margin-bottom-0 line-height-sans-1">
Back to manage your domains
</p>
</a>
{% elif is_analyst_or_superuser%}
<a href="{% url 'admin:registrar_domain_change' domain.id%}" 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 #} {# messages block is under the back breadcrumb link #}
{% if messages %} {% if messages %}
{% for message in messages %} {% for message in messages %}

View file

@ -4,24 +4,38 @@
{% block domain_content %} {% block domain_content %}
{{ block.super }} {{ block.super }}
<div class="margin-top-4 tablet:grid-col-10"> <div class="margin-top-4 tablet:grid-col-10">
{% url 'domain-nameservers' pk=domain.id as url %} {% url 'domain-nameservers' pk=domain.id as url %}
{% if domain.nameservers %} {% if domain.nameservers %}
{% include "includes/summary_item.html" with title='DNS name servers' value=domain.nameservers list='true' edit_link=url %} {% if is_original_creator %}
{% include "includes/summary_item.html" with title='DNS name servers' value=domain.nameservers list='true' edit_link=url %}
{% else %}
{% include "includes/summary_item.html" with title='DNS name servers' value=domain.nameservers list='true' %}
{% endif %}
{% else %} {% else %}
<h2 class="margin-top-neg-1"> DNS name servers </h2> <h2 class="margin-top-neg-1"> DNS name servers </h2>
{% if is_original_creator %}
<p> No DNS name servers have been added yet. Before your domain can be used well need information about your domain name servers.</p> <p> No DNS name servers have been added yet. Before your domain can be used well need information about your domain name servers.</p>
<a class="usa-button margin-bottom-1" href="{{url}}"> Add DNS name servers </a> <a class="usa-button margin-bottom-1" href="{{url}}"> Add DNS name servers </a>
{% else %}
<p>No DNS name servers have been added yet.</p>
{% endif %}
{% endif %} {% endif %}
{% url 'domain-org-name-address' pk=domain.id as url %} {% url 'domain-org-name-address' pk=domain.id as url %}
{% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url %} {% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url %}
{% url 'domain-authorizing-official' pk=domain.id as url %} {% url 'domain-authorizing-official' pk=domain.id as url %}
{% include "includes/summary_item.html" with title='Authorizing official' value=domain.domain_info.authorizing_official contact='true' edit_link=url %} {% if is_original_creator %}
{% include "includes/summary_item.html" with title='Authorizing official' value=domain.domain_info.authorizing_official contact='true' edit_link=url %}
{% else %}
{% include "includes/summary_item.html" with title='Authorizing official' value=domain.domain_info.authorizing_official contact='true'%}
{% endif %}
{% url 'domain-your-contact-information' pk=domain.id as url %} {% url 'domain-your-contact-information' pk=domain.id as url %}
{% include "includes/summary_item.html" with title='Your contact information' value=request.user.contact contact='true' edit_link=url %} {% if is_original_creator %}
{% include "includes/summary_item.html" with title='Your contact information' value=request.user.contact contact='true' edit_link=url %}
{% else %}
{% include "includes/summary_item.html" with title='Contact information' value=request.user.contact contact='true' %}
{% endif %}
{% url 'domain-security-email' pk=domain.id as url %} {% url 'domain-security-email' pk=domain.id as url %}
{% include "includes/summary_item.html" with title='Security email' value=domain.security_email edit_link=url %} {% include "includes/summary_item.html" with title='Security email' value=domain.security_email edit_link=url %}

View file

@ -4,23 +4,23 @@
<nav aria-label="Domain sections"> <nav aria-label="Domain sections">
<ul class="usa-sidenav"> <ul class="usa-sidenav">
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain' pk=domain.id as url %} {% url 'domain' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"
{% if request.path == url %}class="usa-current"{% endif %} {% if request.path == url %}class="usa-current"{% endif %}
> >
Domain overview Domain overview
</a> </a>
</li> </li>
{% if is_original_creator %}
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain-nameservers' pk=domain.id as url %} {% url 'domain-nameservers' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"
{% if request.path == url %}class="usa-current"{% endif %} {% if request.path == url %}class="usa-current"{% endif %}
> >
DNS name servers DNS name servers
</a> </a>
</li> </li>
{% endif %}
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain-org-name-address' pk=domain.id as url %} {% url 'domain-org-name-address' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"
@ -28,8 +28,8 @@
> >
Organization name and mailing address Organization name and mailing address
</a> </a>
</li> </li>
{% if is_original_creator %}
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain-authorizing-official' pk=domain.id as url %} {% url 'domain-authorizing-official' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"
@ -38,16 +38,17 @@
Authorizing official Authorizing official
</a> </a>
</li> </li>
{% endif %}
{% if is_original_creator %}
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain-your-contact-information' pk=domain.id as url %} {% url 'domain-your-contact-information' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"
{% if request.path == url %}class="usa-current"{% endif %} {% if request.path == url %}class="usa-current"{% endif %}
> >
Your contact information Your contact information
</a> </a>
</li> </li>
{% endif %}
<li class="usa-sidenav__item"> <li class="usa-sidenav__item">
{% url 'domain-security-email' pk=domain.id as url %} {% url 'domain-security-email' pk=domain.id as url %}
<a href="{{ url }}" <a href="{{ url }}"

View file

@ -38,7 +38,6 @@ logger = logging.getLogger(__name__)
class DomainView(DomainPermissionView): class DomainView(DomainPermissionView):
"""Domain detail overview page.""" """Domain detail overview page."""
template_name = "domain_detail.html" template_name = "domain_detail.html"

View file

@ -3,7 +3,8 @@
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.mixins import PermissionRequiredMixin
from registrar.models import UserDomainRole, DomainApplication, DomainInvitation from registrar.models import UserDomainRole, DomainApplication, DomainInvitation
import logging
logger = logging.getLogger(__name__)
class PermissionsLoginMixin(PermissionRequiredMixin): class PermissionsLoginMixin(PermissionRequiredMixin):
@ -23,6 +24,8 @@ class DomainPermission(PermissionsLoginMixin):
The user is in self.request.user and the domain needs to be looked 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"] up from the domain's primary key in self.kwargs["pk"]
analysts and superusers are exempt
""" """
# ticket 806 # ticket 806
@ -33,10 +36,15 @@ class DomainPermission(PermissionsLoginMixin):
if not self.request.user.is_authenticated: if not self.request.user.is_authenticated:
return False return False
# user needs to be the creator of the application
# this query is empty if there isn't a domain application with this
# id and this user as creator
user_is_creator: bool = DomainApplication.objects.filter(
creator=self.request.user, id=self.kwargs["pk"]
).exists()
user_is_analyst_or_superuser = self.request.user.is_staff or self.request.user.is_superuser
# user needs to have a role on the domain # user needs to have a role on the domain
if not UserDomainRole.objects.filter( if not user_is_creator and not user_is_analyst_or_superuser:
user=self.request.user, domain__id=self.kwargs["pk"]
).exists():
return False return False
# ticket 796 # ticket 796

View file

@ -5,14 +5,15 @@ import abc # abstract base class
from django.views.generic import DetailView, DeleteView from django.views.generic import DetailView, DeleteView
from registrar.models import Domain, DomainApplication, DomainInvitation from registrar.models import Domain, DomainApplication, DomainInvitation
from registrar.models.domain_information import DomainInformation
from .mixins import ( from .mixins import (
DomainPermission, DomainPermission,
DomainApplicationPermission, DomainApplicationPermission,
DomainInvitationPermission, DomainInvitationPermission,
) )
import logging
logger = logging.getLogger(__name__)
class DomainPermissionView(DomainPermission, DetailView, abc.ABC): class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
"""Abstract base view for domains that enforces permissions. """Abstract base view for domains that enforces permissions.
@ -26,6 +27,17 @@ class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
# variable name in template context for the model object # variable name in template context for the model object
context_object_name = "domain" 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['primary_key'] = self.kwargs["pk"]
context['is_analyst_or_superuser'] = user.is_superuser or user.is_staff
context['is_original_creator'] = DomainInformation.objects.filter(
creator=self.request.user, id=self.kwargs["pk"]
).exists()
return context
# Abstract property enforces NotImplementedError on an attribute. # Abstract property enforces NotImplementedError on an attribute.
@property @property
@abc.abstractmethod @abc.abstractmethod