mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-31 06:56:33 +02:00
added test cases for DNSSEC
This commit is contained in:
parent
6df2a65a90
commit
b43901d675
2 changed files with 339 additions and 33 deletions
|
@ -284,30 +284,21 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
def dnssecdata(self) -> extensions.DNSSECExtension:
|
||||
return self._get_property("dnssecdata")
|
||||
|
||||
@dnssecdata.setter
|
||||
def dnssecdata(
|
||||
self,
|
||||
_dnssecdata: extensions.DNSSECExtension
|
||||
):
|
||||
@dnssecdata.setter # type: ignore
|
||||
def dnssecdata(self, _dnssecdata: extensions.DNSSECExtension):
|
||||
updateParams = {
|
||||
"maxSigLife": _dnssecdata.maxSigLife,
|
||||
"dsData": _dnssecdata.dsData,
|
||||
"keyData": _dnssecdata.keyData,
|
||||
"maxSigLife": _dnssecdata.get("maxSigLife", None),
|
||||
"dsData": _dnssecdata.get("dsData", None),
|
||||
"keyData": _dnssecdata.get("keyData", None),
|
||||
"remAllDsKeyData": True,
|
||||
}
|
||||
request = commands.UpdateDomain(
|
||||
name=self.name
|
||||
)
|
||||
request = commands.UpdateDomain(name=self.name)
|
||||
extension = commands.UpdateDomainDNSSECExtension(**updateParams)
|
||||
request.add_extension(extension)
|
||||
|
||||
try:
|
||||
registry.send(request, cleaned=True)
|
||||
except RegistryError as e:
|
||||
logger.error(
|
||||
"Error adding DNSSEC, code was %s error was %s"
|
||||
% (e.code, e)
|
||||
)
|
||||
logger.error("Error adding DNSSEC, code was %s error was %s" % (e.code, e))
|
||||
raise e
|
||||
|
||||
@nameservers.setter # type: ignore
|
||||
|
@ -1010,9 +1001,9 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
# get extensions info, if there is any
|
||||
# DNSSECExtension is one possible extension, make sure to handle
|
||||
# only DNSSECExtension and not other type extensions
|
||||
extensions = dataResponse.extensions
|
||||
returned_extensions = dataResponse.extensions
|
||||
cleaned["dnssecdata"] = None
|
||||
for extension in extensions:
|
||||
for extension in returned_extensions:
|
||||
if isinstance(extension, extensions.DNSSECExtension):
|
||||
cleaned["dnssecdata"] = extension
|
||||
|
||||
|
|
|
@ -3,9 +3,10 @@ Feature being tested: Registry Integration
|
|||
|
||||
This file tests the various ways in which the registrar interacts with the registry.
|
||||
"""
|
||||
from typing import Mapping, Any
|
||||
from django.test import TestCase
|
||||
from django.db.utils import IntegrityError
|
||||
from unittest.mock import patch, call
|
||||
from unittest.mock import MagicMock, patch, call
|
||||
import datetime
|
||||
from registrar.models import Domain
|
||||
|
||||
|
@ -20,6 +21,7 @@ from .common import MockEppLib
|
|||
from epplibwrapper import (
|
||||
commands,
|
||||
common,
|
||||
extensions,
|
||||
RegistryError,
|
||||
ErrorCode,
|
||||
)
|
||||
|
@ -664,44 +666,357 @@ class TestRegistrantNameservers(TestCase):
|
|||
raise
|
||||
|
||||
|
||||
class TestRegistrantDNSSEC(TestCase):
|
||||
class TestRegistrantDNSSEC(MockEppLib):
|
||||
"""Rule: Registrants may modify their secure DNS data"""
|
||||
|
||||
# helper function to create UpdateDomainDNSSECExtention object for verification
|
||||
def createUpdateExtension(self, dnssecdata: extensions.DNSSECExtension):
|
||||
return commands.UpdateDomainDNSSECExtension(
|
||||
maxSigLife=dnssecdata.maxSigLife,
|
||||
dsData=dnssecdata.dsData,
|
||||
keyData=dnssecdata.keyData,
|
||||
remDsData=None,
|
||||
remKeyData=None,
|
||||
remAllDsKeyData=True,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Background:
|
||||
Given the registrant is logged in
|
||||
And the registrant is the admin on a domain
|
||||
Given the analyst is logged in
|
||||
And a domain exists in the registry
|
||||
"""
|
||||
pass
|
||||
super().setUp()
|
||||
# for the tests, need a domain in the unknown state
|
||||
self.domain, _ = Domain.objects.get_or_create(name="fake.gov")
|
||||
self.addDsData1 = {
|
||||
"keyTag": 1234,
|
||||
"alg": 3,
|
||||
"digestType": 1,
|
||||
"digest": "ec0bdd990b39feead889f0ba613db4adec0bdd99",
|
||||
}
|
||||
self.addDsData2 = {
|
||||
"keyTag": 2345,
|
||||
"alg": 3,
|
||||
"digestType": 1,
|
||||
"digest": "ec0bdd990b39feead889f0ba613db4adecb4adec",
|
||||
}
|
||||
self.keyDataDict = {
|
||||
"flags": 257,
|
||||
"protocol": 3,
|
||||
"alg": 1,
|
||||
"pubKey": "AQPJ////4Q==",
|
||||
}
|
||||
self.dnssecExtensionWithDsData: Mapping[str, Any] = {
|
||||
"dsData": [common.DSData(**self.addDsData1)]
|
||||
}
|
||||
self.dnssecExtensionWithMultDsData: Mapping[str, Any] = {
|
||||
"dsData": [
|
||||
common.DSData(**self.addDsData1),
|
||||
common.DSData(**self.addDsData2),
|
||||
],
|
||||
}
|
||||
self.dnssecExtensionWithKeyData: Mapping[str, Any] = {
|
||||
"maxSigLife": 3215,
|
||||
"keyData": [common.DNSSECKeyData(**self.keyDataDict)],
|
||||
}
|
||||
|
||||
@skip("not implemented yet")
|
||||
def test_user_adds_dns_data(self):
|
||||
def tearDown(self):
|
||||
Domain.objects.all().delete()
|
||||
super().tearDown()
|
||||
|
||||
def test_user_adds_dnssec_data(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNS data
|
||||
Scenario: Registrant adds DNSSEC data.
|
||||
Verify that both the setter and getter are functioning properly
|
||||
|
||||
This test verifies:
|
||||
1 - setter calls UpdateDomain command
|
||||
2 - setter adds the UpdateDNSSECExtension extension to the command
|
||||
3 - setter causes the getter to call info domain on next get from cache
|
||||
4 - getter properly parses dnssecdata from InfoDomain response and sets to cache
|
||||
|
||||
"""
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
def side_effect(_request, cleaned):
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataInfoDomain],
|
||||
extensions=[
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithDsData)
|
||||
],
|
||||
)
|
||||
|
||||
patcher = patch("registrar.models.domain.registry.send")
|
||||
mocked_send = patcher.start()
|
||||
mocked_send.side_effect = side_effect
|
||||
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithDsData
|
||||
# get the DNS SEC extension added to the UpdateDomain command and
|
||||
# verify that it is properly sent
|
||||
# args[0] is the _request sent to registry
|
||||
args, _ = mocked_send.call_args
|
||||
# assert that the extension matches
|
||||
self.assertEquals(
|
||||
args[0].extensions[0],
|
||||
self.createUpdateExtension(
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithDsData)
|
||||
),
|
||||
)
|
||||
# test that the dnssecdata getter is functioning properly
|
||||
dnssecdata_get = self.domain.dnssecdata
|
||||
mocked_send.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
commands.UpdateDomain(
|
||||
name="fake.gov",
|
||||
nsset=None,
|
||||
keyset=None,
|
||||
registrant=None,
|
||||
auth_info=None,
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
call(
|
||||
commands.InfoDomain(
|
||||
name="fake.gov",
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
dnssecdata_get.dsData, self.dnssecExtensionWithDsData["dsData"]
|
||||
)
|
||||
|
||||
patcher.stop()
|
||||
|
||||
def test_dnssec_is_idempotent(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNS data twice, due to a UI glitch
|
||||
|
||||
"""
|
||||
# implementation note: this requires seeing what happens when these are actually
|
||||
# sent like this, and then implementing appropriate mocks for any errors the
|
||||
# registry normally sends in this case
|
||||
raise
|
||||
|
||||
@skip("not implemented yet")
|
||||
This test verifies:
|
||||
1 - UpdateDomain command called twice
|
||||
2 - setter causes the getter to call info domain on next get from cache
|
||||
3 - getter properly parses dnssecdata from InfoDomain response and sets to cache
|
||||
|
||||
"""
|
||||
|
||||
def side_effect(_request, cleaned):
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataInfoDomain],
|
||||
extensions=[
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithDsData)
|
||||
],
|
||||
)
|
||||
|
||||
patcher = patch("registrar.models.domain.registry.send")
|
||||
mocked_send = patcher.start()
|
||||
mocked_send.side_effect = side_effect
|
||||
|
||||
# set the dnssecdata once
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithDsData
|
||||
# set the dnssecdata again
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithDsData
|
||||
# test that the dnssecdata getter is functioning properly
|
||||
dnssecdata_get = self.domain.dnssecdata
|
||||
mocked_send.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
commands.UpdateDomain(
|
||||
name="fake.gov",
|
||||
nsset=None,
|
||||
keyset=None,
|
||||
registrant=None,
|
||||
auth_info=None,
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
call(
|
||||
commands.UpdateDomain(
|
||||
name="fake.gov",
|
||||
nsset=None,
|
||||
keyset=None,
|
||||
registrant=None,
|
||||
auth_info=None,
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
call(
|
||||
commands.InfoDomain(
|
||||
name="fake.gov",
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
dnssecdata_get.dsData, self.dnssecExtensionWithDsData["dsData"]
|
||||
)
|
||||
|
||||
patcher.stop()
|
||||
|
||||
def test_user_adds_dnssec_data_multiple_dsdata(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNSSEC data with multiple DSData.
|
||||
Verify that both the setter and getter are functioning properly
|
||||
|
||||
This test verifies:
|
||||
1 - setter calls UpdateDomain command
|
||||
2 - setter adds the UpdateDNSSECExtension extension to the command
|
||||
3 - setter causes the getter to call info domain on next get from cache
|
||||
4 - getter properly parses dnssecdata from InfoDomain response and sets to cache
|
||||
|
||||
"""
|
||||
|
||||
def side_effect(_request, cleaned):
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataInfoDomain],
|
||||
extensions=[
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithMultDsData)
|
||||
],
|
||||
)
|
||||
|
||||
patcher = patch("registrar.models.domain.registry.send")
|
||||
mocked_send = patcher.start()
|
||||
mocked_send.side_effect = side_effect
|
||||
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithMultDsData
|
||||
# get the DNS SEC extension added to the UpdateDomain command
|
||||
# and verify that it is properly sent
|
||||
# args[0] is the _request sent to registry
|
||||
args, _ = mocked_send.call_args
|
||||
# assert that the extension matches
|
||||
self.assertEquals(
|
||||
args[0].extensions[0],
|
||||
self.createUpdateExtension(
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithMultDsData)
|
||||
),
|
||||
)
|
||||
# test that the dnssecdata getter is functioning properly
|
||||
dnssecdata_get = self.domain.dnssecdata
|
||||
mocked_send.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
commands.UpdateDomain(
|
||||
name="fake.gov",
|
||||
nsset=None,
|
||||
keyset=None,
|
||||
registrant=None,
|
||||
auth_info=None,
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
call(
|
||||
commands.InfoDomain(
|
||||
name="fake.gov",
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
dnssecdata_get.dsData, self.dnssecExtensionWithMultDsData["dsData"]
|
||||
)
|
||||
|
||||
patcher.stop()
|
||||
|
||||
def test_user_adds_dnssec_keydata(self):
|
||||
"""
|
||||
Scenario: Registrant adds DNSSEC data.
|
||||
Verify that both the setter and getter are functioning properly
|
||||
|
||||
This test verifies:
|
||||
1 - setter calls UpdateDomain command
|
||||
2 - setter adds the UpdateDNSSECExtension extension to the command
|
||||
3 - setter causes the getter to call info domain on next get from cache
|
||||
4 - getter properly parses dnssecdata from InfoDomain response and sets to cache
|
||||
|
||||
"""
|
||||
|
||||
def side_effect(_request, cleaned):
|
||||
return MagicMock(
|
||||
res_data=[self.mockDataInfoDomain],
|
||||
extensions=[
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithKeyData)
|
||||
],
|
||||
)
|
||||
|
||||
patcher = patch("registrar.models.domain.registry.send")
|
||||
mocked_send = patcher.start()
|
||||
mocked_send.side_effect = side_effect
|
||||
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithKeyData
|
||||
# get the DNS SEC extension added to the UpdateDomain command
|
||||
# and verify that it is properly sent
|
||||
# args[0] is the _request sent to registry
|
||||
args, _ = mocked_send.call_args
|
||||
# assert that the extension matches
|
||||
self.assertEquals(
|
||||
args[0].extensions[0],
|
||||
self.createUpdateExtension(
|
||||
extensions.DNSSECExtension(**self.dnssecExtensionWithKeyData)
|
||||
),
|
||||
)
|
||||
# test that the dnssecdata getter is functioning properly
|
||||
dnssecdata_get = self.domain.dnssecdata
|
||||
mocked_send.assert_has_calls(
|
||||
[
|
||||
call(
|
||||
commands.UpdateDomain(
|
||||
name="fake.gov",
|
||||
nsset=None,
|
||||
keyset=None,
|
||||
registrant=None,
|
||||
auth_info=None,
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
call(
|
||||
commands.InfoDomain(
|
||||
name="fake.gov",
|
||||
),
|
||||
cleaned=True,
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEquals(
|
||||
dnssecdata_get.keyData, self.dnssecExtensionWithKeyData["keyData"]
|
||||
)
|
||||
|
||||
patcher.stop()
|
||||
|
||||
def test_update_is_unsuccessful(self):
|
||||
"""
|
||||
Scenario: An update to the dns data is unsuccessful
|
||||
When an error is returned from epplibwrapper
|
||||
Then a user-friendly error message is returned for displaying on the web
|
||||
"""
|
||||
raise
|
||||
|
||||
def side_effect(_request, cleaned):
|
||||
raise RegistryError(code=ErrorCode.PARAMETER_VALUE_RANGE_ERROR)
|
||||
|
||||
patcher = patch("registrar.models.domain.registry.send")
|
||||
mocked_send = patcher.start()
|
||||
mocked_send.side_effect = side_effect
|
||||
|
||||
# if RegistryError is raised, view formats user-friendly
|
||||
# error message if error is_client_error, is_session_error, or
|
||||
# is_server_error; so test for those conditions
|
||||
with self.assertRaises(RegistryError) as err:
|
||||
self.domain.dnssecdata = self.dnssecExtensionWithDsData
|
||||
self.assertTrue(
|
||||
err.is_client_error() or err.is_session_error() or err.is_server_error()
|
||||
)
|
||||
|
||||
patcher.stop()
|
||||
|
||||
|
||||
class TestAnalystClientHold(MockEppLib):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue