Implement domain security email page with stubs for EPP

This commit is contained in:
rachidatecs 2023-05-17 10:39:49 -04:00
parent c3f1fcba27
commit c01a0276e5
No known key found for this signature in database
GPG key ID: 3CEBBFA7325E5525
10 changed files with 143 additions and 3 deletions

View file

@ -83,6 +83,11 @@ urlpatterns = [
views.DomainNameserversView.as_view(),
name="domain-nameservers",
),
path(
"domain/<int:pk>/securityemail",
views.DomainSecurityEmailView.as_view(),
name="domain-security-email",
),
path(
"domain/<int:pk>/users/add",
views.DomainAddUserView.as_view(),

View file

@ -1,2 +1,2 @@
from .application_wizard import *
from .domain import DomainAddUserForm, NameserverFormset
from .domain import DomainAddUserForm, NameserverFormset, DomainSecurityEmailForm

View file

@ -22,3 +22,10 @@ NameserverFormset = formset_factory(
DomainNameserverForm,
extra=1,
)
class DomainSecurityEmailForm(forms.Form):
"""Form for adding or editing a security email to a domain."""
security_email = forms.EmailField(label="Security email")

View file

@ -235,6 +235,19 @@ class Domain(TimeStampedModel):
# nothing.
logger.warn("TODO: Fake setting nameservers to %s", new_nameservers)
def security_email(self) -> str:
"""Get the security email for this domain.
TODO: call EPP to get this info instead of returning fake data.
"""
return "mayor@igorville.gov"
def set_security_email(self, new_security_email: str):
"""Set the security email for this domain."""
# TODO: call EPP to set these values in the registry instead of doing
# nothing.
logger.warn("TODO: Fake setting security email to %s", new_security_email)
@property
def roid(self):
return self._get_property("roid")

View file

@ -0,0 +1,27 @@
{% extends "domain_base.html" %}
{% load static field_helpers %}
{% block title %}Domain security email | {{ domain.name }} | {% endblock %}
{% block domain_content %}
<h1>Domain security email</h1>
<p>We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain. Security emails are made public and included in the <a href="https://federalist-877ab29f-16f6-4f12-961c-96cf064cf070.sites.pages.cloud.gov/site/cisagov/getgov-home/about/data/">.gov domain data</a> we provide.</p>
<p>A security contact should be capable of evaluating or triaging security reports for your entire domain. Use a team email address, not an individuals email. We recommend using an alias, like security@domain.gov.</p>
{% include "includes/required_fields.html" %}
<form class="usa-form usa-form--large" method="post" novalidate>
{% csrf_token %}
{% input_with_errors form.security_email %}
<button
type="submit"
class="usa-button"
>Add security email</button>
</form>
{% endblock %} {# domain_content #}

View file

@ -40,7 +40,7 @@
</li>
<li class="usa-sidenav__item">
{% url 'todo' as url %}
{% url 'domain-security-email' pk=domain.id as url %}
<a href="{{ url }}"
{% if request.path == url %}class="usa-current"{% endif %}
>

View file

@ -1063,6 +1063,11 @@ class TestDomainPermissions(TestWithDomainPermissions):
)
self.assertEqual(response.status_code, 302)
response = self.client.get(
reverse("domain-security-email", kwargs={"pk": self.domain.id})
)
self.assertEqual(response.status_code, 302)
def test_no_domain_role(self):
"""Logged in but no role gets 403 Forbidden."""
self.client.force_login(self.user)
@ -1282,6 +1287,38 @@ class TestDomainDetail(TestWithDomainPermissions, WebTest):
# the field.
self.assertContains(result, "This field is required", count=2, status_code=200)
def test_domain_security_email(self):
"""Can load domain's security email page."""
page = self.client.get(
reverse("domain-security-email", kwargs={"pk": self.domain.id})
)
self.assertContains(page, "Domain security email")
def test_domain_security_email_form(self):
"""Adding a security email works.
Uses self.app WebTest because we need to interact with forms.
"""
security_email_page = self.app.get(
reverse("domain-security-email", kwargs={"pk": self.domain.id})
)
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
security_email_page.form["security_email"] = "mayor@igorville.gov"
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
with less_console_noise(): # swallow log warning message
result = security_email_page.form.submit()
self.assertEqual(result.status_code, 302)
self.assertEqual(
result["Location"],
reverse("domain-security-email", kwargs={"pk": self.domain.id}),
)
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
success_page = result.follow()
self.assertContains(
success_page, "The security email for this domain have been updated"
)
class TestApplicationStatus(TestWithUser, WebTest):
def setUp(self):

View file

@ -2,6 +2,7 @@ from .application import *
from .domain import (
DomainView,
DomainNameserversView,
DomainSecurityEmailView,
DomainUsersView,
DomainAddUserView,
DomainInvitationDeleteView,

View file

@ -12,7 +12,7 @@ from django.views.generic.edit import DeleteView, FormMixin
from registrar.models import Domain, DomainInvitation, User, UserDomainRole
from ..forms import DomainAddUserForm, NameserverFormset
from ..forms import DomainAddUserForm, NameserverFormset, DomainSecurityEmailForm
from ..utility.email import send_templated_email, EmailSendingError
from .utility import DomainPermission
@ -96,6 +96,55 @@ class DomainNameserversView(DomainPermission, FormMixin, DetailView):
return super().form_valid(formset)
class DomainSecurityEmailView(DomainPermission, FormMixin, DetailView):
"""Domain security email editing view."""
model = Domain
template_name = "domain_security_email.html"
context_object_name = "domain"
form_class = DomainSecurityEmailForm
def get_initial(self):
"""The initial value for the form."""
domain = self.get_object()
initial = super().get_initial()
initial["security_email"] = domain.security_email()
return initial
def get_success_url(self):
"""Redirect to the overview page for the domain."""
return reverse("domain-security-email", kwargs={"pk": self.object.pk})
def post(self, request, *args, **kwargs):
"""Formset submission posts to this view."""
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
# there is a valid email address in the form
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
"""The form is valid, call setter in model."""
# Set the security email from the from
try:
new_email = form.cleaned_data["security_email"]
except KeyError:
# no server information in this field, skip it
pass
domain = self.get_object()
domain.set_security_email(new_email)
messages.success(
self.request, "The security email for this domain have been updated"
)
# superclass has the redirect
return redirect(self.get_success_url())
class DomainUsersView(DomainPermission, DetailView):
"""User management page in the domain details."""

View file

@ -52,6 +52,7 @@
10038 OUTOFSCOPE http://app:8080/users
10038 OUTOFSCOPE http://app:8080/users/add
10038 OUTOFSCOPE http://app:8080/nameservers
10038 OUTOFSCOPE http://app:8080/securityemail
10038 OUTOFSCOPE http://app:8080/delete
10038 OUTOFSCOPE http://app:8080/withdraw
10038 OUTOFSCOPE http://app:8080/withdrawconfirmed