Do not apply reserved list to domain restore (#3191)

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
This commit is contained in:
Ben McIlwain
2026-07-31 17:23:37 +00:00
committed by GitHub
parent 92b684d7ec
commit b5ae51a036
2 changed files with 2 additions and 21 deletions
@@ -25,7 +25,6 @@ import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccoun
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 static java.time.ZoneOffset.UTC;
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 @@ import org.joda.money.Money;
* @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 @@ public final class DomainRestoreRequestFlow implements MutatingFlow {
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());
@@ -53,7 +53,6 @@ import google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException;
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 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
}
@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 @@ class DomainRestoreRequestFlowTest extends ResourceFlowTestCase<DomainRestoreReq
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");