diff --git a/core/src/main/java/google/registry/tools/UpdateDomainCommand.java b/core/src/main/java/google/registry/tools/UpdateDomainCommand.java index a0e99f703..8a84d7078 100644 --- a/core/src/main/java/google/registry/tools/UpdateDomainCommand.java +++ b/core/src/main/java/google/registry/tools/UpdateDomainCommand.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.domain.rgp.GracePeriodStatus.AUTO_RENEW; +import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE; import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED; import static google.registry.persistence.transaction.TransactionManagerFactory.tm; import static google.registry.util.PreconditionsUtils.checkArgumentPresent; @@ -139,6 +140,11 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand { + " deleted at the end of its current registration period.") Boolean autorenews; + @Parameter( + names = {"--force_in_pending_delete"}, + description = "Force a superuser update even on domains that are in pending delete") + boolean forceInPendingDelete; + @Override protected void initMutatingEppToolCommand() { if (!nameservers.isEmpty()) { @@ -186,6 +192,12 @@ final class UpdateDomainCommand extends CreateOrUpdateDomainCommand { "The domain '%s' has status SERVER_UPDATE_PROHIBITED. Verify that you are allowed " + "to make updates, and if so, use the domain_unlock command to enable updates.", domain); + checkArgument( + !domainBase.getStatusValues().contains(PENDING_DELETE) || forceInPendingDelete, + "The domain '%s' has status PENDING_DELETE. Verify that you really are intending to " + + "update a domain in pending delete (this is uncommon), and if so, pass the " + + "--force_in_pending_delete parameter to allow this update.", + domain); // Use TreeSets so that the results are always in the same order (this makes testing easier). Set addAdminsThisDomain = new TreeSet<>(addAdmins); diff --git a/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java b/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java index 8c15348ba..b4ca09ff2 100644 --- a/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java +++ b/core/src/test/java/google/registry/tools/UpdateDomainCommandTest.java @@ -16,6 +16,7 @@ package google.registry.tools; import static com.google.common.truth.Truth.assertThat; import static google.registry.model.domain.rgp.GracePeriodStatus.AUTO_RENEW; +import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE; import static google.registry.model.eppcommon.StatusValue.SERVER_UPDATE_PROHIBITED; import static google.registry.model.reporting.HistoryEntry.Type.DOMAIN_CREATE; import static google.registry.testing.DatabaseHelper.createTld; @@ -334,6 +335,39 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase adminResourceKey1 = adminContact1.createVKey(); + VKey adminResourceKey2 = adminContact2.createVKey(); + VKey techResourceKey1 = techContact1.createVKey(); + VKey techResourceKey2 = techContact2.createVKey(); + + persistResource( + newDomainBase("example.tld") + .asBuilder() + .setContacts( + ImmutableSet.of( + DesignatedContact.create(DesignatedContact.Type.ADMIN, adminResourceKey1), + DesignatedContact.create(DesignatedContact.Type.ADMIN, adminResourceKey2), + DesignatedContact.create(DesignatedContact.Type.TECH, techResourceKey1), + DesignatedContact.create(DesignatedContact.Type.TECH, techResourceKey2))) + .setStatusValues(ImmutableSet.of(PENDING_DELETE)) + .build()); + + runCommandForced( + "--client=NewRegistrar", + "--admins=crr-admin2,crr-admin3", + "--techs=crr-tech2,crr-tech3", + "--superuser", + "--force_in_pending_delete", + "example.tld"); + eppVerifier.expectSuperuser().verifySent("domain_update_set_contacts.xml"); + } + @Test void testFailure_cantUpdateRegistryLockedDomainEvenAsSuperuser() { HostResource host = persistActiveHost("ns1.zdns.google"); @@ -356,7 +390,30 @@ class UpdateDomainCommandTest extends EppToolCommandTestCase> nameservers = ImmutableSet.of(host.createVKey()); + persistResource( + newDomainBase("example.tld") + .asBuilder() + .setStatusValues(ImmutableSet.of(PENDING_DELETE)) + .setNameservers(nameservers) + .build()); + + Exception e = + assertThrows( + IllegalArgumentException.class, + () -> + runCommandForced( + "--client=NewRegistrar", + "--statuses=clientRenewProhibited,serverHold", + "--superuser", + "example.tld")); + assertThat(e).hasMessageThat().contains("The domain 'example.tld' has status PENDING_DELETE."); } @Test