mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-06-10 14:34:43 +02:00
Merge pull request #1347 from cisagov/dk/1217-domain-expiration-epp
Issue #1217 - Domain expiration date - EPP
This commit is contained in:
commit
310da70913
4 changed files with 102 additions and 5 deletions
|
@ -736,7 +736,7 @@ class DomainAdmin(ListHeaderAdmin):
|
|||
search_help_text = "Search by domain name."
|
||||
change_form_template = "django/admin/domain_change_form.html"
|
||||
change_list_template = "django/admin/domain_change_list.html"
|
||||
readonly_fields = ["state"]
|
||||
readonly_fields = ["state", "expiration_date"]
|
||||
|
||||
def export_data_type(self, request):
|
||||
# match the CSV example with all the fields
|
||||
|
|
|
@ -211,12 +211,56 @@ class Domain(TimeStampedModel, DomainHelper):
|
|||
|
||||
@Cache
|
||||
def registry_expiration_date(self) -> date:
|
||||
"""Get or set the `ex_date` element from the registry."""
|
||||
return self._get_property("ex_date")
|
||||
"""Get or set the `ex_date` element from the registry.
|
||||
Additionally, update the expiration date in the registrar"""
|
||||
try:
|
||||
self.expiration_date = self._get_property("ex_date")
|
||||
self.save()
|
||||
return self.expiration_date
|
||||
except Exception as e:
|
||||
# exception raised during the save to registrar
|
||||
logger.error(f"error updating expiration date in registrar: {e}")
|
||||
raise (e)
|
||||
|
||||
@registry_expiration_date.setter # type: ignore
|
||||
def registry_expiration_date(self, ex_date: date):
|
||||
pass
|
||||
"""
|
||||
Direct setting of the expiration date in the registry is not implemented.
|
||||
|
||||
To update the expiration date, use renew_domain method."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR):
|
||||
"""
|
||||
Renew the domain to a length and unit of time relative to the current
|
||||
expiration date.
|
||||
|
||||
Default length and unit of time are 1 year.
|
||||
"""
|
||||
# if no expiration date from registry, set to today
|
||||
try:
|
||||
cur_exp_date = self.registry_expiration_date
|
||||
except KeyError:
|
||||
logger.warning("current expiration date not set; setting to today")
|
||||
cur_exp_date = date.today()
|
||||
|
||||
# create RenewDomain request
|
||||
request = commands.RenewDomain(name=self.name, cur_exp_date=cur_exp_date, period=epp.Period(length, unit))
|
||||
|
||||
try:
|
||||
# update expiration date in registry, and set the updated
|
||||
# expiration date in the registrar, and in the cache
|
||||
self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date
|
||||
self.expiration_date = self._cache["ex_date"]
|
||||
self.save()
|
||||
except RegistryError as err:
|
||||
# if registry error occurs, log the error, and raise it as well
|
||||
logger.error(f"registry error renewing domain: {err}")
|
||||
raise (err)
|
||||
except Exception as e:
|
||||
# exception raised during the save to registrar
|
||||
logger.error(f"error updating expiration date in registrar: {e}")
|
||||
raise (e)
|
||||
|
||||
@Cache
|
||||
def password(self) -> str:
|
||||
|
|
|
@ -556,6 +556,7 @@ class MockEppLib(TestCase):
|
|||
avail=...,
|
||||
addrs=...,
|
||||
registrant=...,
|
||||
ex_date=...,
|
||||
):
|
||||
self.auth_info = auth_info
|
||||
self.cr_date = cr_date
|
||||
|
@ -565,6 +566,7 @@ class MockEppLib(TestCase):
|
|||
self.avail = avail # use for CheckDomain
|
||||
self.addrs = addrs
|
||||
self.registrant = registrant
|
||||
self.ex_date = ex_date
|
||||
|
||||
def dummyInfoContactResultData(
|
||||
self,
|
||||
|
@ -811,6 +813,11 @@ class MockEppLib(TestCase):
|
|||
],
|
||||
)
|
||||
|
||||
mockRenewedDomainExpDate = fakedEppObject(
|
||||
"fake.gov",
|
||||
ex_date=datetime.date(2023, 5, 25),
|
||||
)
|
||||
|
||||
def _mockDomainName(self, _name, _avail=False):
|
||||
return MagicMock(
|
||||
res_data=[
|
||||
|
@ -870,6 +877,8 @@ class MockEppLib(TestCase):
|
|||
return self.mockCheckDomainCommand(_request, cleaned)
|
||||
case commands.DeleteDomain:
|
||||
return self.mockDeleteDomainCommands(_request, cleaned)
|
||||
case commands.RenewDomain:
|
||||
return self.mockRenewDomainCommand(_request, cleaned)
|
||||
case _:
|
||||
return MagicMock(res_data=[self.mockDataInfoHosts])
|
||||
|
||||
|
@ -890,6 +899,15 @@ class MockEppLib(TestCase):
|
|||
raise RegistryError(code=ErrorCode.OBJECT_ASSOCIATION_PROHIBITS_OPERATION)
|
||||
return None
|
||||
|
||||
def mockRenewDomainCommand(self, _request, cleaned):
|
||||
if getattr(_request, "name", None) == "fake-error.gov":
|
||||
raise RegistryError(code=ErrorCode.PARAMETER_VALUE_RANGE_ERROR)
|
||||
else:
|
||||
return MagicMock(
|
||||
res_data=[self.mockRenewedDomainExpDate],
|
||||
code=ErrorCode.COMMAND_COMPLETED_SUCCESSFULLY,
|
||||
)
|
||||
|
||||
def mockInfoDomainCommands(self, _request, cleaned):
|
||||
request_name = getattr(_request, "name", None)
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class TestDomainCache(MockEppLib):
|
|||
self.assertFalse("avail" in domain._cache.keys())
|
||||
|
||||
# using a setter should clear the cache
|
||||
domain.registry_expiration_date = datetime.date.today()
|
||||
domain.dnssecdata = []
|
||||
self.assertEquals(domain._cache, {})
|
||||
|
||||
# send should have been called only once
|
||||
|
@ -1953,6 +1953,41 @@ class TestRegistrantDNSSEC(MockEppLib):
|
|||
self.assertTrue(err.is_client_error() or err.is_session_error() or err.is_server_error())
|
||||
|
||||
|
||||
class TestExpirationDate(MockEppLib):
|
||||
"""User may renew expiration date by a number of units of time"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Domain exists in registry
|
||||
"""
|
||||
super().setUp()
|
||||
# for the tests, need a domain in the ready state
|
||||
self.domain, _ = Domain.objects.get_or_create(name="fake.gov", state=Domain.State.READY)
|
||||
# for the test, need a domain that will raise an exception
|
||||
self.domain_w_error, _ = Domain.objects.get_or_create(name="fake-error.gov", state=Domain.State.READY)
|
||||
|
||||
def tearDown(self):
|
||||
Domain.objects.all().delete()
|
||||
super().tearDown()
|
||||
|
||||
def test_expiration_date_setter_not_implemented(self):
|
||||
"""assert that the setter for expiration date is not implemented and will raise error"""
|
||||
with self.assertRaises(NotImplementedError):
|
||||
self.domain.registry_expiration_date = datetime.date.today()
|
||||
|
||||
def test_renew_domain(self):
|
||||
"""assert that the renew_domain sets new expiration date in cache and saves to registrar"""
|
||||
self.domain.renew_domain()
|
||||
test_date = datetime.date(2023, 5, 25)
|
||||
self.assertEquals(self.domain._cache["ex_date"], test_date)
|
||||
self.assertEquals(self.domain.expiration_date, test_date)
|
||||
|
||||
def test_renew_domain_error(self):
|
||||
"""assert that the renew_domain raises an exception when registry raises error"""
|
||||
with self.assertRaises(RegistryError):
|
||||
self.domain_w_error.renew_domain()
|
||||
|
||||
|
||||
class TestAnalystClientHold(MockEppLib):
|
||||
"""Rule: Analysts may suspend or restore a domain by using client hold"""
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue