mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-06 01:35:22 +02:00
Fix merge conflicts
This commit is contained in:
commit
9be47b754f
8 changed files with 396 additions and 189 deletions
|
@ -45,7 +45,7 @@ except NameError:
|
|||
# Attn: these imports should NOT be at the top of the file
|
||||
try:
|
||||
from .client import CLIENT, commands
|
||||
from .errors import RegistryError, ErrorCode
|
||||
from .errors import RegistryError, ErrorCode, CANNOT_CONTACT_REGISTRY, GENERIC_ERROR
|
||||
from epplib.models import common, info
|
||||
from epplib.responses import extensions
|
||||
from epplib import responses
|
||||
|
@ -61,4 +61,6 @@ __all__ = [
|
|||
"info",
|
||||
"ErrorCode",
|
||||
"RegistryError",
|
||||
"CANNOT_CONTACT_REGISTRY",
|
||||
"GENERIC_ERROR",
|
||||
]
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
from enum import IntEnum
|
||||
|
||||
CANNOT_CONTACT_REGISTRY = "Update failed. Cannot contact the registry."
|
||||
GENERIC_ERROR = "Value entered was wrong."
|
||||
|
||||
|
||||
class ErrorCode(IntEnum):
|
||||
"""
|
||||
|
|
|
@ -652,6 +652,9 @@ SESSION_COOKIE_SAMESITE = "Lax"
|
|||
# instruct browser to only send cookie via HTTPS
|
||||
SESSION_COOKIE_SECURE = True
|
||||
|
||||
# session engine to cache session information
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||
|
||||
# ~ Set by django.middleware.clickjacking.XFrameOptionsMiddleware
|
||||
# prevent clickjacking by instructing the browser not to load
|
||||
# our site within an iframe
|
||||
|
|
|
@ -260,7 +260,6 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
"""Creates the host object in the registry
|
||||
doesn't add the created host to the domain
|
||||
returns ErrorCode (int)"""
|
||||
logger.info("Creating host")
|
||||
if addrs is not None:
|
||||
addresses = [epp.Ip(addr=addr) for addr in addrs]
|
||||
request = commands.CreateHost(name=host, addrs=addresses)
|
||||
|
@ -818,7 +817,7 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
and errorCode != ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY
|
||||
):
|
||||
# TODO- ticket #433 look here for error handling
|
||||
raise Exception("Unable to add contact to registry")
|
||||
raise RegistryError(code=errorCode)
|
||||
|
||||
# contact doesn't exist on the domain yet
|
||||
logger.info("_set_singleton_contact()-> contact has been added to the registry")
|
||||
|
@ -1245,7 +1244,6 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
count = 0
|
||||
while not exitEarly and count < 3:
|
||||
try:
|
||||
logger.info("Getting domain info from epp")
|
||||
req = commands.InfoDomain(name=self.name)
|
||||
domainInfoResponse = registry.send(req, cleaned=True)
|
||||
exitEarly = True
|
||||
|
@ -1684,74 +1682,84 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
"""Contact registry for info about a domain."""
|
||||
try:
|
||||
# get info from registry
|
||||
dataResponse = self._get_or_create_domain()
|
||||
data = dataResponse.res_data[0]
|
||||
# extract properties from response
|
||||
# (Ellipsis is used to mean "null")
|
||||
cache = {
|
||||
"auth_info": getattr(data, "auth_info", ...),
|
||||
"_contacts": getattr(data, "contacts", ...),
|
||||
"cr_date": getattr(data, "cr_date", ...),
|
||||
"ex_date": getattr(data, "ex_date", ...),
|
||||
"_hosts": getattr(data, "hosts", ...),
|
||||
"name": getattr(data, "name", ...),
|
||||
"registrant": getattr(data, "registrant", ...),
|
||||
"statuses": getattr(data, "statuses", ...),
|
||||
"tr_date": getattr(data, "tr_date", ...),
|
||||
"up_date": getattr(data, "up_date", ...),
|
||||
}
|
||||
# remove null properties (to distinguish between "a value of None" and null)
|
||||
cleaned = {k: v for k, v in cache.items() if v is not ...}
|
||||
data_response = self._get_or_create_domain()
|
||||
cache = self._extract_data_from_response(data_response)
|
||||
|
||||
# remove null properties (to distinguish between "a value of None" and null)
|
||||
cleaned = self._remove_null_properties(cache)
|
||||
|
||||
# statuses can just be a list no need to keep the epp object
|
||||
if "statuses" in cleaned:
|
||||
cleaned["statuses"] = [status.state for status in cleaned["statuses"]]
|
||||
|
||||
# get extensions info, if there is any
|
||||
# DNSSECExtension is one possible extension, make sure to handle
|
||||
# only DNSSECExtension and not other type extensions
|
||||
returned_extensions = dataResponse.extensions
|
||||
cleaned["dnssecdata"] = None
|
||||
for extension in returned_extensions:
|
||||
if isinstance(extension, extensions.DNSSECExtension):
|
||||
cleaned["dnssecdata"] = extension
|
||||
cleaned["dnssecdata"] = self._get_dnssec_data(data_response.extensions)
|
||||
|
||||
# Capture and store old hosts and contacts from cache if they exist
|
||||
old_cache_hosts = self._cache.get("hosts")
|
||||
old_cache_contacts = self._cache.get("contacts")
|
||||
|
||||
# get contact info, if there are any
|
||||
if (
|
||||
fetch_contacts
|
||||
and "_contacts" in cleaned
|
||||
and isinstance(cleaned["_contacts"], list)
|
||||
and len(cleaned["_contacts"]) > 0
|
||||
):
|
||||
cleaned["contacts"] = self._fetch_contacts(cleaned["_contacts"])
|
||||
# We're only getting contacts, so retain the old
|
||||
# hosts that existed in cache (if they existed)
|
||||
# and pass them along.
|
||||
if fetch_contacts:
|
||||
cleaned["contacts"] = self._get_contacts(cleaned.get("_contacts", []))
|
||||
if old_cache_hosts is not None:
|
||||
logger.debug("resetting cleaned['hosts'] to old_cache_hosts")
|
||||
cleaned["hosts"] = old_cache_hosts
|
||||
|
||||
# get nameserver info, if there are any
|
||||
if (
|
||||
fetch_hosts
|
||||
and "_hosts" in cleaned
|
||||
and isinstance(cleaned["_hosts"], list)
|
||||
and len(cleaned["_hosts"])
|
||||
):
|
||||
cleaned["hosts"] = self._fetch_hosts(cleaned["_hosts"])
|
||||
# We're only getting hosts, so retain the old
|
||||
# contacts that existed in cache (if they existed)
|
||||
# and pass them along.
|
||||
if fetch_hosts:
|
||||
cleaned["hosts"] = self._get_hosts(cleaned.get("_hosts", []))
|
||||
if old_cache_contacts is not None:
|
||||
cleaned["contacts"] = old_cache_contacts
|
||||
# replace the prior cache with new data
|
||||
|
||||
self._cache = cleaned
|
||||
|
||||
except RegistryError as e:
|
||||
logger.error(e)
|
||||
|
||||
def _extract_data_from_response(self, data_response):
|
||||
data = data_response.res_data[0]
|
||||
return {
|
||||
"auth_info": getattr(data, "auth_info", ...),
|
||||
"_contacts": getattr(data, "contacts", ...),
|
||||
"cr_date": getattr(data, "cr_date", ...),
|
||||
"ex_date": getattr(data, "ex_date", ...),
|
||||
"_hosts": getattr(data, "hosts", ...),
|
||||
"name": getattr(data, "name", ...),
|
||||
"registrant": getattr(data, "registrant", ...),
|
||||
"statuses": getattr(data, "statuses", ...),
|
||||
"tr_date": getattr(data, "tr_date", ...),
|
||||
"up_date": getattr(data, "up_date", ...),
|
||||
}
|
||||
|
||||
def _remove_null_properties(self, cache):
|
||||
return {k: v for k, v in cache.items() if v is not ...}
|
||||
|
||||
def _get_dnssec_data(self, response_extensions):
|
||||
# get extensions info, if there is any
|
||||
# DNSSECExtension is one possible extension, make sure to handle
|
||||
# only DNSSECExtension and not other type extensions
|
||||
dnssec_data = None
|
||||
for extension in response_extensions:
|
||||
if isinstance(extension, extensions.DNSSECExtension):
|
||||
dnssec_data = extension
|
||||
return dnssec_data
|
||||
|
||||
def _get_contacts(self, contacts):
|
||||
choices = PublicContact.ContactTypeChoices
|
||||
# We expect that all these fields get populated,
|
||||
# so we can create these early, rather than waiting.
|
||||
cleaned_contacts = {
|
||||
choices.ADMINISTRATIVE: None,
|
||||
choices.SECURITY: None,
|
||||
choices.TECHNICAL: None,
|
||||
}
|
||||
if contacts and isinstance(contacts, list) and len(contacts) > 0:
|
||||
cleaned_contacts = self._fetch_contacts(contacts)
|
||||
return cleaned_contacts
|
||||
|
||||
def _get_hosts(self, hosts):
|
||||
cleaned_hosts = []
|
||||
if hosts and isinstance(hosts, list):
|
||||
cleaned_hosts = self._fetch_hosts(hosts)
|
||||
return cleaned_hosts
|
||||
|
||||
def _get_or_create_public_contact(self, public_contact: PublicContact):
|
||||
"""Tries to find a PublicContact object in our DB.
|
||||
If it can't, it'll create it. Returns PublicContact"""
|
||||
|
|
|
@ -34,6 +34,8 @@ from epplibwrapper import (
|
|||
responses,
|
||||
)
|
||||
|
||||
from registrar.models.utility.contact_error import ContactError, ContactErrorCodes
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -792,7 +794,7 @@ class MockEppLib(TestCase):
|
|||
]
|
||||
)
|
||||
|
||||
def _handleCheckDomain(self, _request):
|
||||
def mockCheckDomainCommand(self, _request, cleaned):
|
||||
if "gsa.gov" in getattr(_request, "names", None):
|
||||
return self._mockDomainName("gsa.gov", True)
|
||||
elif "GSA.gov" in getattr(_request, "names", None):
|
||||
|
@ -809,31 +811,16 @@ class MockEppLib(TestCase):
|
|||
registry is imported from epplibwrapper
|
||||
returns objects that simulate what would be in a epp response
|
||||
but only relevant pieces for tests"""
|
||||
if (
|
||||
isinstance(_request, commands.CreateContact)
|
||||
and getattr(_request, "id", None) == "fail"
|
||||
and self.mockedSendFunction.call_count == 3
|
||||
):
|
||||
# use this for when a contact is being updated
|
||||
# sets the second send() to fail
|
||||
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
||||
|
||||
if (
|
||||
isinstance(_request, commands.DeleteDomain)
|
||||
and getattr(_request, "name", None) == "failDelete.gov"
|
||||
):
|
||||
name = getattr(_request, "name", None)
|
||||
fake_nameserver = "ns1.failDelete.gov"
|
||||
if name in fake_nameserver:
|
||||
raise RegistryError(
|
||||
code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION
|
||||
)
|
||||
|
||||
match type(_request):
|
||||
case commands.InfoDomain:
|
||||
return self.mockInfoDomainCommands(_request, cleaned)
|
||||
case commands.InfoContact:
|
||||
return self.mockInfoContactCommands(_request, cleaned)
|
||||
case commands.CreateContact:
|
||||
return self.mockCreateContactCommands(_request, cleaned)
|
||||
case commands.UpdateDomain:
|
||||
return self.mockUpdateDomainCommands(_request, cleaned)
|
||||
case commands.CreateHost:
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataHostChange],
|
||||
|
@ -844,15 +831,15 @@ class MockEppLib(TestCase):
|
|||
res_data=[self.mockDataHostChange],
|
||||
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
|
||||
)
|
||||
case commands.UpdateDomain:
|
||||
return self.mockUpdateDomainCommands(_request, cleaned)
|
||||
case commands.DeleteHost:
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataHostChange],
|
||||
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
|
||||
)
|
||||
case commands.CheckDomain:
|
||||
return self._handleCheckDomain(_request)
|
||||
return self.mockCheckDomainCommand(_request, cleaned)
|
||||
case commands.DeleteDomain:
|
||||
return self.mockDeleteDomainCommands(_request, cleaned)
|
||||
case _:
|
||||
return MagicMock(res_data=[self.mockDataInfoHosts])
|
||||
|
||||
|
@ -864,6 +851,17 @@ class MockEppLib(TestCase):
|
|||
res_data=[self.mockDataHostChange],
|
||||
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
|
||||
)
|
||||
|
||||
def mockDeleteDomainCommands(self, _request, cleaned):
|
||||
if getattr(_request, "name", None) == "failDelete.gov":
|
||||
name = getattr(_request, "name", None)
|
||||
fake_nameserver = "ns1.failDelete.gov"
|
||||
if name in fake_nameserver:
|
||||
raise RegistryError(
|
||||
code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def mockInfoDomainCommands(self, _request, cleaned):
|
||||
request_name = getattr(_request, "name", None)
|
||||
|
@ -925,6 +923,24 @@ class MockEppLib(TestCase):
|
|||
|
||||
return MagicMock(res_data=[mocked_result])
|
||||
|
||||
def mockCreateContactCommands(self, _request, cleaned):
|
||||
if (
|
||||
getattr(_request, "id", None) == "fail"
|
||||
and self.mockedSendFunction.call_count == 3
|
||||
):
|
||||
# use this for when a contact is being updated
|
||||
# sets the second send() to fail
|
||||
raise RegistryError(code=ErrorCode.OBJECT_EXISTS)
|
||||
elif getattr(_request, "email", None) == "test@failCreate.gov":
|
||||
# use this for when a contact is being updated
|
||||
# mocks a registry error on creation
|
||||
raise RegistryError(code=None)
|
||||
elif getattr(_request, "email", None) == "test@contactError.gov":
|
||||
# use this for when a contact is being updated
|
||||
# mocks a contact error on creation
|
||||
raise ContactError(code=ContactErrorCodes.CONTACT_TYPE_NONE)
|
||||
return MagicMock(res_data=[self.mockDataInfoHosts])
|
||||
|
||||
def setUp(self):
|
||||
"""mock epp send function as this will fail locally"""
|
||||
self.mockSendPatch = patch("registrar.models.domain.registry.send")
|
||||
|
|
|
@ -1554,6 +1554,78 @@ class TestDomainSecurityEmail(TestDomainOverview):
|
|||
success_page, "The security email for this domain has been updated"
|
||||
)
|
||||
|
||||
def test_security_email_form_messages(self):
|
||||
"""
|
||||
Test against the success and error messages that are defined in the view
|
||||
"""
|
||||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
form_data_registry_error = {
|
||||
"security_email": "test@failCreate.gov",
|
||||
}
|
||||
|
||||
form_data_contact_error = {
|
||||
"security_email": "test@contactError.gov",
|
||||
}
|
||||
|
||||
form_data_success = {
|
||||
"security_email": "test@something.gov",
|
||||
}
|
||||
|
||||
test_cases = [
|
||||
(
|
||||
"RegistryError",
|
||||
form_data_registry_error,
|
||||
"Update failed. Cannot contact the registry.",
|
||||
),
|
||||
("ContactError", form_data_contact_error, "Value entered was wrong."),
|
||||
(
|
||||
"RegistrySuccess",
|
||||
form_data_success,
|
||||
"The security email for this domain has been updated.",
|
||||
),
|
||||
# Add more test cases with different scenarios here
|
||||
]
|
||||
|
||||
for test_name, data, expected_message in test_cases:
|
||||
response = self.client.post(
|
||||
reverse("domain-security-email", kwargs={"pk": self.domain.id}),
|
||||
data=data,
|
||||
follow=True,
|
||||
)
|
||||
|
||||
# Check the response status code, content, or any other relevant assertions
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Check if the expected message tag is set
|
||||
if test_name == "RegistryError" or test_name == "ContactError":
|
||||
message_tag = "error"
|
||||
elif test_name == "RegistrySuccess":
|
||||
message_tag = "success"
|
||||
else:
|
||||
# Handle other cases if needed
|
||||
message_tag = "info" # Change to the appropriate default
|
||||
|
||||
# Check the message tag
|
||||
messages = list(response.context["messages"])
|
||||
self.assertEqual(len(messages), 1)
|
||||
message = messages[0]
|
||||
self.assertEqual(message.tags, message_tag)
|
||||
self.assertEqual(message.message, expected_message)
|
||||
|
||||
def test_domain_overview_blocked_for_ineligible_user(self):
|
||||
"""We could easily duplicate this test for all domain management
|
||||
views, but a single url test should be solid enough since all domain
|
||||
management pages share the same permissions class"""
|
||||
self.user.status = User.RESTRICTED
|
||||
self.user.save()
|
||||
home_page = self.app.get("/")
|
||||
self.assertContains(home_page, "igorville.gov")
|
||||
with less_console_noise():
|
||||
response = self.client.get(reverse("domain", kwargs={"pk": self.domain.id}))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
|
||||
class TestDomainDNSSEC(TestDomainOverview):
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from registrar.models import (
|
|||
UserDomainRole,
|
||||
)
|
||||
from registrar.models.public_contact import PublicContact
|
||||
from registrar.models.utility.contact_error import ContactError
|
||||
|
||||
from ..forms import (
|
||||
ContactForm,
|
||||
|
@ -41,6 +42,8 @@ from epplibwrapper import (
|
|||
common,
|
||||
extensions,
|
||||
RegistryError,
|
||||
CANNOT_CONTACT_REGISTRY,
|
||||
GENERIC_ERROR,
|
||||
)
|
||||
|
||||
from ..utility.email import send_templated_email, EmailSendingError
|
||||
|
@ -50,7 +53,81 @@ from .utility import DomainPermissionView, DomainInvitationPermissionDeleteView
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DomainView(DomainPermissionView):
|
||||
class DomainBaseView(DomainPermissionView):
|
||||
"""
|
||||
Base View for the Domain. Handles getting and setting the domain
|
||||
in session cache on GETs. Also provides methods for getting
|
||||
and setting the domain in cache
|
||||
"""
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self._get_domain(request)
|
||||
context = self.get_context_data(object=self.object)
|
||||
return self.render_to_response(context)
|
||||
|
||||
def _get_domain(self, request):
|
||||
"""
|
||||
get domain from session cache or from db and set
|
||||
to self.object
|
||||
set session to self for downstream functions to
|
||||
update session cache
|
||||
"""
|
||||
self.session = request.session
|
||||
# domain:private_key is the session key to use for
|
||||
# caching the domain in the session
|
||||
domain_pk = "domain:" + str(self.kwargs.get("pk"))
|
||||
cached_domain = self.session.get(domain_pk)
|
||||
|
||||
if cached_domain:
|
||||
self.object = cached_domain
|
||||
else:
|
||||
self.object = self.get_object()
|
||||
self._update_session_with_domain()
|
||||
|
||||
def _update_session_with_domain(self):
|
||||
"""
|
||||
update domain in the session cache
|
||||
"""
|
||||
domain_pk = "domain:" + str(self.kwargs.get("pk"))
|
||||
self.session[domain_pk] = self.object
|
||||
|
||||
|
||||
class DomainFormBaseView(DomainBaseView, FormMixin):
|
||||
"""
|
||||
Form Base View for the Domain. Handles getting and setting
|
||||
domain in cache when dealing with domain forms. Provides
|
||||
implementations of post, form_valid and form_invalid.
|
||||
"""
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form submission posts to this view.
|
||||
|
||||
This post method harmonizes using DomainBaseView and FormMixin
|
||||
"""
|
||||
self._get_domain(request)
|
||||
form = self.get_form()
|
||||
if form.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
# updates session cache with domain
|
||||
self._update_session_with_domain()
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_valid(form)
|
||||
|
||||
def form_invalid(self, form):
|
||||
# updates session cache with domain
|
||||
self._update_session_with_domain()
|
||||
|
||||
# superclass has the redirect
|
||||
return super().form_invalid(form)
|
||||
|
||||
|
||||
class DomainView(DomainBaseView):
|
||||
|
||||
"""Domain detail overview page."""
|
||||
|
||||
template_name = "domain_detail.html"
|
||||
|
@ -58,10 +135,10 @@ class DomainView(DomainPermissionView):
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
default_email = Domain().get_default_security_contact().email
|
||||
default_email = self.object.get_default_security_contact().email
|
||||
context["default_security_email"] = default_email
|
||||
|
||||
security_email = self.get_object().get_security_email()
|
||||
security_email = self.object.get_security_email()
|
||||
if security_email is None or security_email == default_email:
|
||||
context["security_email"] = None
|
||||
return context
|
||||
|
@ -69,7 +146,7 @@ class DomainView(DomainPermissionView):
|
|||
return context
|
||||
|
||||
|
||||
class DomainOrgNameAddressView(DomainPermissionView, FormMixin):
|
||||
class DomainOrgNameAddressView(DomainFormBaseView):
|
||||
"""Organization name and mailing address view"""
|
||||
|
||||
model = Domain
|
||||
|
@ -80,25 +157,13 @@ class DomainOrgNameAddressView(DomainPermissionView, FormMixin):
|
|||
def get_form_kwargs(self, *args, **kwargs):
|
||||
"""Add domain_info.organization_name instance to make a bound form."""
|
||||
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
||||
form_kwargs["instance"] = self.get_object().domain_info
|
||||
form_kwargs["instance"] = self.object.domain_info
|
||||
return form_kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
"""Redirect to the overview page for the domain."""
|
||||
return reverse("domain-org-name-address", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form submission posts to this view.
|
||||
|
||||
This post method harmonizes using DetailView and FormMixin together.
|
||||
"""
|
||||
self.object = self.get_object()
|
||||
form = self.get_form()
|
||||
if form.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
"""The form is valid, save the organization name and mailing address."""
|
||||
form.save()
|
||||
|
@ -111,7 +176,7 @@ class DomainOrgNameAddressView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class DomainAuthorizingOfficialView(DomainPermissionView, FormMixin):
|
||||
class DomainAuthorizingOfficialView(DomainFormBaseView):
|
||||
"""Domain authorizing official editing view."""
|
||||
|
||||
model = Domain
|
||||
|
@ -122,25 +187,13 @@ class DomainAuthorizingOfficialView(DomainPermissionView, FormMixin):
|
|||
def get_form_kwargs(self, *args, **kwargs):
|
||||
"""Add domain_info.authorizing_official instance to make a bound form."""
|
||||
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
||||
form_kwargs["instance"] = self.get_object().domain_info.authorizing_official
|
||||
form_kwargs["instance"] = self.object.domain_info.authorizing_official
|
||||
return form_kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
"""Redirect to the overview page for the domain."""
|
||||
return reverse("domain-authorizing-official", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form submission posts to this view.
|
||||
|
||||
This post method harmonizes using DetailView and FormMixin together.
|
||||
"""
|
||||
self.object = self.get_object()
|
||||
form = self.get_form()
|
||||
if form.is_valid():
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
return self.form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
"""The form is valid, save the authorizing official."""
|
||||
form.save()
|
||||
|
@ -153,13 +206,13 @@ class DomainAuthorizingOfficialView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class DomainDNSView(DomainPermissionView):
|
||||
class DomainDNSView(DomainBaseView):
|
||||
"""DNS Information View."""
|
||||
|
||||
template_name = "domain_dns.html"
|
||||
|
||||
|
||||
class DomainNameserversView(DomainPermissionView, FormMixin):
|
||||
class DomainNameserversView(DomainFormBaseView):
|
||||
"""Domain nameserver editing view."""
|
||||
|
||||
template_name = "domain_nameservers.html"
|
||||
|
@ -167,8 +220,7 @@ class DomainNameserversView(DomainPermissionView, FormMixin):
|
|||
|
||||
def get_initial(self):
|
||||
"""The initial value for the form (which is a formset here)."""
|
||||
domain = self.get_object()
|
||||
nameservers = domain.nameservers
|
||||
nameservers = self.object.nameservers
|
||||
initial_data = []
|
||||
|
||||
if nameservers is not None:
|
||||
|
@ -204,16 +256,6 @@ class DomainNameserversView(DomainPermissionView, FormMixin):
|
|||
form.fields["server"].required = False
|
||||
return formset
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Formset submission posts to this view."""
|
||||
self.object = self.get_object()
|
||||
formset = self.get_form()
|
||||
|
||||
if formset.is_valid():
|
||||
return self.form_valid(formset)
|
||||
else:
|
||||
return self.form_invalid(formset)
|
||||
|
||||
def form_valid(self, formset):
|
||||
"""The formset is valid, perform something with it."""
|
||||
|
||||
|
@ -226,8 +268,7 @@ class DomainNameserversView(DomainPermissionView, FormMixin):
|
|||
except KeyError:
|
||||
# no server information in this field, skip it
|
||||
pass
|
||||
domain = self.get_object()
|
||||
domain.nameservers = nameservers
|
||||
self.object.nameservers = nameservers
|
||||
|
||||
messages.success(
|
||||
self.request, "The name servers for this domain have been updated."
|
||||
|
@ -237,7 +278,7 @@ class DomainNameserversView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(formset)
|
||||
|
||||
|
||||
class DomainDNSSECView(DomainPermissionView, FormMixin):
|
||||
class DomainDNSSECView(DomainFormBaseView):
|
||||
"""Domain DNSSEC editing view."""
|
||||
|
||||
template_name = "domain_dnssec.html"
|
||||
|
@ -247,9 +288,7 @@ class DomainDNSSECView(DomainPermissionView, FormMixin):
|
|||
"""The initial value for the form (which is a formset here)."""
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
self.domain = self.get_object()
|
||||
|
||||
has_dnssec_records = self.domain.dnssecdata is not None
|
||||
has_dnssec_records = self.object.dnssecdata is not None
|
||||
|
||||
# Create HTML for the modal button
|
||||
modal_button = (
|
||||
|
@ -266,16 +305,16 @@ class DomainDNSSECView(DomainPermissionView, FormMixin):
|
|||
|
||||
def get_success_url(self):
|
||||
"""Redirect to the DNSSEC page for the domain."""
|
||||
return reverse("domain-dns-dnssec", kwargs={"pk": self.domain.pk})
|
||||
return reverse("domain-dns-dnssec", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form submission posts to this view."""
|
||||
self.domain = self.get_object()
|
||||
self._get_domain(request)
|
||||
form = self.get_form()
|
||||
if form.is_valid():
|
||||
if "disable_dnssec" in request.POST:
|
||||
try:
|
||||
self.domain.dnssecdata = {}
|
||||
self.object.dnssecdata = {}
|
||||
except RegistryError as err:
|
||||
errmsg = "Error removing existing DNSSEC record(s)."
|
||||
logger.error(errmsg + ": " + err)
|
||||
|
@ -290,7 +329,7 @@ class DomainDNSSECView(DomainPermissionView, FormMixin):
|
|||
return self.form_valid(form)
|
||||
|
||||
|
||||
class DomainDsDataView(DomainPermissionView, FormMixin):
|
||||
class DomainDsDataView(DomainFormBaseView):
|
||||
"""Domain DNSSEC ds data editing view."""
|
||||
|
||||
template_name = "domain_dsdata.html"
|
||||
|
@ -299,8 +338,7 @@ class DomainDsDataView(DomainPermissionView, FormMixin):
|
|||
|
||||
def get_initial(self):
|
||||
"""The initial value for the form (which is a formset here)."""
|
||||
domain = self.get_object()
|
||||
dnssecdata: extensions.DNSSECExtension = domain.dnssecdata
|
||||
dnssecdata: extensions.DNSSECExtension = self.object.dnssecdata
|
||||
initial_data = []
|
||||
|
||||
if dnssecdata is not None:
|
||||
|
@ -341,8 +379,7 @@ class DomainDsDataView(DomainPermissionView, FormMixin):
|
|||
# set the dnssec_ds_confirmed flag in the context for this view
|
||||
# based either on the existence of DS Data in the domain,
|
||||
# or on the flag stored in the session
|
||||
domain = self.get_object()
|
||||
dnssecdata: extensions.DNSSECExtension = domain.dnssecdata
|
||||
dnssecdata: extensions.DNSSECExtension = self.object.dnssecdata
|
||||
|
||||
if dnssecdata is not None and dnssecdata.dsData is not None:
|
||||
self.request.session["dnssec_ds_confirmed"] = True
|
||||
|
@ -354,7 +391,7 @@ class DomainDsDataView(DomainPermissionView, FormMixin):
|
|||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Formset submission posts to this view."""
|
||||
self.object = self.get_object()
|
||||
self._get_domain(request)
|
||||
formset = self.get_form()
|
||||
|
||||
if "confirm-ds" in request.POST:
|
||||
|
@ -394,9 +431,8 @@ class DomainDsDataView(DomainPermissionView, FormMixin):
|
|||
# as valid; this can happen if form has been added but
|
||||
# not been interacted with; in that case, want to ignore
|
||||
pass
|
||||
domain = self.get_object()
|
||||
try:
|
||||
domain.dnssecdata = dnssecdata
|
||||
self.object.dnssecdata = dnssecdata
|
||||
except RegistryError as err:
|
||||
errmsg = "Error updating DNSSEC data in the registry."
|
||||
logger.error(errmsg)
|
||||
|
@ -411,7 +447,7 @@ class DomainDsDataView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(formset)
|
||||
|
||||
|
||||
class DomainKeyDataView(DomainPermissionView, FormMixin):
|
||||
class DomainKeyDataView(DomainFormBaseView):
|
||||
"""Domain DNSSEC key data editing view."""
|
||||
|
||||
template_name = "domain_keydata.html"
|
||||
|
@ -420,8 +456,7 @@ class DomainKeyDataView(DomainPermissionView, FormMixin):
|
|||
|
||||
def get_initial(self):
|
||||
"""The initial value for the form (which is a formset here)."""
|
||||
domain = self.get_object()
|
||||
dnssecdata: extensions.DNSSECExtension = domain.dnssecdata
|
||||
dnssecdata: extensions.DNSSECExtension = self.object.dnssecdata
|
||||
initial_data = []
|
||||
|
||||
if dnssecdata is not None:
|
||||
|
@ -462,8 +497,7 @@ class DomainKeyDataView(DomainPermissionView, FormMixin):
|
|||
# set the dnssec_key_confirmed flag in the context for this view
|
||||
# based either on the existence of Key Data in the domain,
|
||||
# or on the flag stored in the session
|
||||
domain = self.get_object()
|
||||
dnssecdata: extensions.DNSSECExtension = domain.dnssecdata
|
||||
dnssecdata: extensions.DNSSECExtension = self.object.dnssecdata
|
||||
|
||||
if dnssecdata is not None and dnssecdata.keyData is not None:
|
||||
self.request.session["dnssec_key_confirmed"] = True
|
||||
|
@ -475,7 +509,7 @@ class DomainKeyDataView(DomainPermissionView, FormMixin):
|
|||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Formset submission posts to this view."""
|
||||
self.object = self.get_object()
|
||||
self._get_domain(request)
|
||||
formset = self.get_form()
|
||||
|
||||
if "confirm-key" in request.POST:
|
||||
|
@ -514,9 +548,8 @@ class DomainKeyDataView(DomainPermissionView, FormMixin):
|
|||
except KeyError:
|
||||
# no server information in this field, skip it
|
||||
pass
|
||||
domain = self.get_object()
|
||||
try:
|
||||
domain.dnssecdata = dnssecdata
|
||||
self.object.dnssecdata = dnssecdata
|
||||
except RegistryError as err:
|
||||
errmsg = "Error updating DNSSEC data in the registry."
|
||||
logger.error(errmsg)
|
||||
|
@ -531,7 +564,7 @@ class DomainKeyDataView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(formset)
|
||||
|
||||
|
||||
class DomainYourContactInformationView(DomainPermissionView, FormMixin):
|
||||
class DomainYourContactInformationView(DomainFormBaseView):
|
||||
"""Domain your contact information editing view."""
|
||||
|
||||
template_name = "domain_your_contact_information.html"
|
||||
|
@ -547,16 +580,6 @@ class DomainYourContactInformationView(DomainPermissionView, FormMixin):
|
|||
"""Redirect to the your contact information for the domain."""
|
||||
return reverse("domain-your-contact-information", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form 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."""
|
||||
|
||||
|
@ -571,7 +594,7 @@ class DomainYourContactInformationView(DomainPermissionView, FormMixin):
|
|||
return super().form_valid(form)
|
||||
|
||||
|
||||
class DomainSecurityEmailView(DomainPermissionView, FormMixin):
|
||||
class DomainSecurityEmailView(DomainFormBaseView):
|
||||
"""Domain security email editing view."""
|
||||
|
||||
template_name = "domain_security_email.html"
|
||||
|
@ -579,9 +602,8 @@ class DomainSecurityEmailView(DomainPermissionView, FormMixin):
|
|||
|
||||
def get_initial(self):
|
||||
"""The initial value for the form."""
|
||||
domain = self.get_object()
|
||||
initial = super().get_initial()
|
||||
security_contact = domain.security_contact
|
||||
security_contact = self.object.security_contact
|
||||
if security_contact is None or security_contact.email == "dotgov@cisa.dhs.gov":
|
||||
initial["security_email"] = None
|
||||
return initial
|
||||
|
@ -592,16 +614,6 @@ class DomainSecurityEmailView(DomainPermissionView, FormMixin):
|
|||
"""Redirect to the security email page for the domain."""
|
||||
return reverse("domain-security-email", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
"""Form 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."""
|
||||
|
||||
|
@ -612,33 +624,44 @@ class DomainSecurityEmailView(DomainPermissionView, FormMixin):
|
|||
if new_email is None or new_email.strip() == "":
|
||||
new_email = PublicContact.get_default_security().email
|
||||
|
||||
domain = self.get_object()
|
||||
contact = domain.security_contact
|
||||
contact = self.object.security_contact
|
||||
|
||||
# If no default is created for security_contact,
|
||||
# then we cannot connect to the registry.
|
||||
if contact is None:
|
||||
messages.error(self.request, "Update failed. Cannot contact the registry.")
|
||||
messages.error(self.request, CANNOT_CONTACT_REGISTRY)
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
contact.email = new_email
|
||||
contact.save()
|
||||
|
||||
messages.success(
|
||||
self.request, "The security email for this domain has been updated."
|
||||
)
|
||||
try:
|
||||
contact.save()
|
||||
except RegistryError as Err:
|
||||
if Err.is_connection_error():
|
||||
messages.error(self.request, CANNOT_CONTACT_REGISTRY)
|
||||
logger.error(f"Registry connection error: {Err}")
|
||||
else:
|
||||
messages.error(self.request, GENERIC_ERROR)
|
||||
logger.error(f"Registry error: {Err}")
|
||||
except ContactError as Err:
|
||||
messages.error(self.request, GENERIC_ERROR)
|
||||
logger.error(f"Generic registry error: {Err}")
|
||||
else:
|
||||
messages.success(
|
||||
self.request, "The security email for this domain has been updated."
|
||||
)
|
||||
|
||||
# superclass has the redirect
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
|
||||
class DomainUsersView(DomainPermissionView):
|
||||
class DomainUsersView(DomainBaseView):
|
||||
"""User management page in the domain details."""
|
||||
|
||||
template_name = "domain_users.html"
|
||||
|
||||
|
||||
class DomainAddUserView(DomainPermissionView, FormMixin):
|
||||
class DomainAddUserView(DomainFormBaseView):
|
||||
"""Inside of a domain's user management, a form for adding users.
|
||||
|
||||
Multiple inheritance is used here for permissions, form handling, and
|
||||
|
@ -651,15 +674,6 @@ class DomainAddUserView(DomainPermissionView, FormMixin):
|
|||
def get_success_url(self):
|
||||
return reverse("domain-users", kwargs={"pk": self.object.pk})
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
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 _domain_abs_url(self):
|
||||
"""Get an absolute URL for this domain."""
|
||||
return self.request.build_absolute_uri(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue