Merge pull request #1164 from cisagov/rjm/1103-security-email-registry-error-handling

Issue 1103 - security email registry error handling
This commit is contained in:
rachidatecs 2023-10-18 15:58:53 -04:00 committed by GitHub
commit e80a328fae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 121 additions and 15 deletions

View file

@ -45,7 +45,7 @@ except NameError:
# Attn: these imports should NOT be at the top of the file # Attn: these imports should NOT be at the top of the file
try: try:
from .client import CLIENT, commands 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.models import common, info
from epplib.responses import extensions from epplib.responses import extensions
from epplib import responses from epplib import responses
@ -61,4 +61,6 @@ __all__ = [
"info", "info",
"ErrorCode", "ErrorCode",
"RegistryError", "RegistryError",
"CANNOT_CONTACT_REGISTRY",
"GENERIC_ERROR",
] ]

View file

@ -1,5 +1,8 @@
from enum import IntEnum from enum import IntEnum
CANNOT_CONTACT_REGISTRY = "Update failed. Cannot contact the registry."
GENERIC_ERROR = "Value entered was wrong."
class ErrorCode(IntEnum): class ErrorCode(IntEnum):
""" """

View file

@ -818,7 +818,7 @@ class Domain(TimeStampedModel, DomainHelper):
and errorCode != ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY and errorCode != ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY
): ):
# TODO- ticket #433 look here for error handling # 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 # contact doesn't exist on the domain yet
logger.info("_set_singleton_contact()-> contact has been added to the registry") logger.info("_set_singleton_contact()-> contact has been added to the registry")

View file

@ -33,6 +33,8 @@ from epplibwrapper import (
ErrorCode, ErrorCode,
) )
from registrar.models.utility.contact_error import ContactError, ContactErrorCodes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -793,14 +795,8 @@ class MockEppLib(TestCase):
return self.mockInfoContactCommands(_request, cleaned) return self.mockInfoContactCommands(_request, cleaned)
elif isinstance(_request, commands.UpdateDomain): elif isinstance(_request, commands.UpdateDomain):
return self.mockUpdateDomainCommands(_request, cleaned) return self.mockUpdateDomainCommands(_request, cleaned)
elif ( elif isinstance(_request, commands.CreateContact):
isinstance(_request, commands.CreateContact) return self.mockCreateContactCommands(_request, cleaned)
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)
elif isinstance(_request, commands.CreateHost): elif isinstance(_request, commands.CreateHost):
return MagicMock( return MagicMock(
res_data=[self.mockDataHostChange], res_data=[self.mockDataHostChange],
@ -897,6 +893,24 @@ class MockEppLib(TestCase):
return MagicMock(res_data=[mocked_result]) 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): def setUp(self):
"""mock epp send function as this will fail locally""" """mock epp send function as this will fail locally"""
self.mockSendPatch = patch("registrar.models.domain.registry.send") self.mockSendPatch = patch("registrar.models.domain.registry.send")

View file

@ -1554,6 +1554,78 @@ class TestDomainSecurityEmail(TestDomainOverview):
success_page, "The security email for this domain has been updated" 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): class TestDomainDNSSEC(TestDomainOverview):

View file

@ -23,6 +23,7 @@ from registrar.models import (
UserDomainRole, UserDomainRole,
) )
from registrar.models.public_contact import PublicContact from registrar.models.public_contact import PublicContact
from registrar.models.utility.contact_error import ContactError
from ..forms import ( from ..forms import (
ContactForm, ContactForm,
@ -41,6 +42,8 @@ from epplibwrapper import (
common, common,
extensions, extensions,
RegistryError, RegistryError,
CANNOT_CONTACT_REGISTRY,
GENERIC_ERROR,
) )
from ..utility.email import send_templated_email, EmailSendingError from ..utility.email import send_templated_email, EmailSendingError
@ -618,12 +621,24 @@ class DomainSecurityEmailView(DomainPermissionView, FormMixin):
# If no default is created for security_contact, # If no default is created for security_contact,
# then we cannot connect to the registry. # then we cannot connect to the registry.
if contact is None: 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()) return redirect(self.get_success_url())
contact.email = new_email contact.email = new_email
contact.save()
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( messages.success(
self.request, "The security email for this domain has been updated." self.request, "The security email for this domain has been updated."
) )