From da40e423c821db7dc409b3096cf546bc1cd7f85b Mon Sep 17 00:00:00 2001 From: Ben McIlwain Date: Fri, 31 Jul 2026 11:59:39 -0400 Subject: [PATCH] Do not apply reserved list to domain restore Per ICANN's Expired Registration Recovery Policy, all gTLD registries must offer a Redemption Grace Period (RGP) of 30 days during which deleted domains may be restored. Registry reservation lists should not block domain restore commands during the RGP. This change removes the reserved list check in DomainRestoreRequestFlow, reverting the behavior originally added in CL 72341125 (July 2014) that explicitly disallowed restoring reserved domains. Unit tests have been updated to confirm restoring reserved domains succeeds for standard registrar accounts. BUG=b/539548743 TAG=agy CONV=d5dff534-f924-4bba-a58e-74091dc5f496 --- .../domain/DomainRestoreRequestFlow.java | 4 ---- .../domain/DomainRestoreRequestFlowTest.java | 19 ++----------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java index 5b65832c4fa..4ccdfdfcd84 100644 --- a/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java +++ b/core/src/main/java/google/registry/flows/domain/DomainRestoreRequestFlow.java @@ -25,7 +25,6 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEvent; import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage; import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge; -import static google.registry.flows.domain.DomainFlowUtils.verifyNotReserved; import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked; import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_RESTORE; @@ -35,7 +34,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.google.common.net.InternetDomainName; import google.registry.flows.EppException; import google.registry.flows.EppException.CommandUseErrorException; import google.registry.flows.EppException.StatusProhibitsOperationException; @@ -101,7 +99,6 @@ * @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException} * @error {@link DomainFlowUtils.CurrencyUnitMismatchException} * @error {@link DomainFlowUtils.CurrencyValueScaleException} - * @error {@link DomainFlowUtils.DomainReservedException} * @error {@link DomainFlowUtils.FeesMismatchException} * @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException} * @error {@link DomainFlowUtils.MissingBillingAccountMapException} @@ -221,7 +218,6 @@ private void verifyRestoreAllowed( verifyOptionalAuthInfo(authInfo, existingDomain); if (!isSuperuser) { verifyResourceOwnership(registrarId, existingDomain); - verifyNotReserved(InternetDomainName.from(targetId), false); verifyPremiumNameIsNotBlocked(targetId, now, registrarId); checkAllowedAccessToTld(registrarId, existingDomain.getTld()); checkHasBillingAccount(registrarId, existingDomain.getTld()); diff --git a/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java index 6ca88a20fcd..ddb72029cf2 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainRestoreRequestFlowTest.java @@ -53,7 +53,6 @@ import google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException; import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException; import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException; -import google.registry.flows.domain.DomainFlowUtils.DomainReservedException; import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException; import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException; import google.registry.flows.domain.DomainFlowUtils.MissingBillingAccountMapException; @@ -397,15 +396,14 @@ void testSuccess_premiumNotBlocked_andNoRenewal_std_v1() throws Exception { } @Test - void testSuccess_superuserOverridesReservedList() throws Exception { + void testSuccess_reservedDomain() throws Exception { persistResource( Tld.get("tld") .asBuilder() .setReservedLists(persistReservedList("tld-reserved", "example,FULLY_BLOCKED")) .build()); persistPendingDeleteDomain(); - runFlowAssertResponse( - CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("generic_success_response.xml")); + runFlowAssertResponse(loadFile("generic_success_response.xml")); } @Test @@ -631,19 +629,6 @@ void testFailure_premiumBlocked_std_v1() throws Exception { assertAboutEppExceptions().that(thrown).marshalsToXml(); } - @Test - void testFailure_reservedBlocked() throws Exception { - createTld("tld"); - persistResource( - Tld.get("tld") - .asBuilder() - .setReservedLists(persistReservedList("tld-reserved", "example,FULLY_BLOCKED")) - .build()); - persistPendingDeleteDomain(); - EppException thrown = assertThrows(DomainReservedException.class, this::runFlow); - assertAboutEppExceptions().that(thrown).marshalsToXml(); - } - @Test void testFailure_premiumNotAcked() throws Exception { createTld("example");