mirror of
https://github.com/google/nomulus.git
synced 2025-05-15 17:07:15 +02:00
Send deletion poll messages when requested by superuser
Otherwise, registrars will never receive a notification through EPP that a domain has been synchronously deleted by us. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=234172289
This commit is contained in:
parent
067756722d
commit
94a2681127
3 changed files with 84 additions and 20 deletions
|
@ -15,6 +15,7 @@
|
|||
package google.registry.flows.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static google.registry.flows.FlowUtils.persistEntityChanges;
|
||||
import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
|
||||
import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
|
||||
|
@ -81,7 +82,6 @@ import google.registry.model.eppinput.EppInput;
|
|||
import google.registry.model.eppoutput.EppResponse;
|
||||
import google.registry.model.poll.PendingActionNotificationResponse.DomainPendingActionNotificationResponse;
|
||||
import google.registry.model.poll.PollMessage;
|
||||
import google.registry.model.poll.PollMessage.OneTime;
|
||||
import google.registry.model.registry.Registry;
|
||||
import google.registry.model.registry.Registry.TldType;
|
||||
import google.registry.model.reporting.DomainTransactionRecord;
|
||||
|
@ -177,16 +177,13 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
|||
? Duration.ZERO
|
||||
// By default, this should be 30 days of grace, and 5 days of pending delete.
|
||||
: redemptionGracePeriodLength.plus(pendingDeleteLength);
|
||||
HistoryEntry historyEntry = buildHistoryEntry(
|
||||
existingDomain, registry, now, durationUntilDelete, inAddGracePeriod);
|
||||
HistoryEntry historyEntry =
|
||||
buildHistoryEntry(existingDomain, registry, now, durationUntilDelete, inAddGracePeriod);
|
||||
DateTime deletionTime = now.plus(durationUntilDelete);
|
||||
if (durationUntilDelete.equals(Duration.ZERO)) {
|
||||
builder.setDeletionTime(now).setStatusValues(null);
|
||||
} else {
|
||||
DateTime deletionTime = now.plus(durationUntilDelete);
|
||||
DateTime redemptionTime = now.plus(redemptionGracePeriodLength);
|
||||
PollMessage.OneTime deletePollMessage =
|
||||
createDeletePollMessage(existingDomain, historyEntry, deletionTime);
|
||||
entitiesToSave.add(deletePollMessage);
|
||||
asyncTaskEnqueuer.enqueueAsyncResave(
|
||||
existingDomain, now, ImmutableSortedSet.of(redemptionTime, deletionTime));
|
||||
builder.setDeletionTime(deletionTime)
|
||||
|
@ -196,13 +193,23 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
|||
.setGracePeriods(ImmutableSet.of(GracePeriod.createWithoutBillingEvent(
|
||||
GracePeriodStatus.REDEMPTION,
|
||||
redemptionTime,
|
||||
clientId)))
|
||||
.setDeletePollMessage(Key.create(deletePollMessage));
|
||||
clientId)));
|
||||
// Note: The expiration time is unchanged, so if it's before the new deletion time, there will
|
||||
// be a "phantom autorenew" where the expiration time advances but no billing event or poll
|
||||
// message are produced (since we are ending the autorenew recurrences at "now" below). For
|
||||
// now at least this is working as intended.
|
||||
}
|
||||
|
||||
// Enqueue the deletion poll message if the delete is asynchronous or if requested by a
|
||||
// superuser (i.e. the registrar didn't request this delete and thus should be notified even if
|
||||
// it is synchronous).
|
||||
if (!durationUntilDelete.equals(Duration.ZERO) || isSuperuser) {
|
||||
PollMessage.OneTime deletePollMessage =
|
||||
createDeletePollMessage(existingDomain, historyEntry, deletionTime);
|
||||
entitiesToSave.add(deletePollMessage);
|
||||
builder.setDeletePollMessage(Key.create(deletePollMessage));
|
||||
}
|
||||
|
||||
DomainBase newDomain = builder.build();
|
||||
updateForeignKeyIndexDeletionTime(newDomain);
|
||||
handlePendingTransferOnDelete(existingDomain, newDomain, now, historyEntry);
|
||||
|
@ -296,15 +303,26 @@ public final class DomainDeleteFlow implements TransactionalFlow {
|
|||
.build();
|
||||
}
|
||||
|
||||
private OneTime createDeletePollMessage(
|
||||
DomainBase existingResource, HistoryEntry historyEntry, DateTime deletionTime) {
|
||||
private PollMessage.OneTime createDeletePollMessage(
|
||||
DomainBase existingDomain, HistoryEntry historyEntry, DateTime deletionTime) {
|
||||
Optional<MetadataExtension> metadataExtension =
|
||||
eppInput.getSingleExtension(MetadataExtension.class);
|
||||
boolean hasMetadataMessage =
|
||||
metadataExtension.isPresent() && !isNullOrEmpty(metadataExtension.get().getReason());
|
||||
String message =
|
||||
isSuperuser
|
||||
? (hasMetadataMessage
|
||||
? metadataExtension.get().getReason()
|
||||
: "Deleted by registry administrator.")
|
||||
: "Domain deleted.";
|
||||
return new PollMessage.OneTime.Builder()
|
||||
.setClientId(existingResource.getCurrentSponsorClientId())
|
||||
.setClientId(existingDomain.getCurrentSponsorClientId())
|
||||
.setEventTime(deletionTime)
|
||||
.setMsg("Domain deleted.")
|
||||
.setResponseData(ImmutableList.of(
|
||||
.setMsg(message)
|
||||
.setResponseData(
|
||||
ImmutableList.of(
|
||||
DomainPendingActionNotificationResponse.create(
|
||||
existingResource.getFullyQualifiedDomainName(), true, trid, deletionTime)))
|
||||
existingDomain.getFullyQualifiedDomainName(), true, trid, deletionTime)))
|
||||
.setParent(historyEntry)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -406,8 +406,6 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
.plus(Registry.get("tld").getRedemptionGracePeriodLength())
|
||||
.plus(Registry.get("tld").getPendingDeleteLength()))
|
||||
.and()
|
||||
.hasDeletePollMessage()
|
||||
.and()
|
||||
.hasExactlyStatusValues(StatusValue.INACTIVE, StatusValue.PENDING_DELETE)
|
||||
.and()
|
||||
.hasOneHistoryEntryEachOfTypes(DOMAIN_CREATE, DOMAIN_DELETE);
|
||||
|
@ -427,13 +425,20 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
clock.nowUtc().plus(Registry.get("tld").getRedemptionGracePeriodLength()),
|
||||
"TheRegistrar",
|
||||
null));
|
||||
assertDeletionPollMessageFor(resource, "Domain deleted.");
|
||||
}
|
||||
|
||||
private void assertDeletionPollMessageFor(DomainBase domain, String expectedMessage) {
|
||||
// There should be a future poll message at the deletion time. The previous autorenew poll
|
||||
// message should now be deleted.
|
||||
DateTime deletionTime = resource.getDeletionTime();
|
||||
assertAboutDomains().that(domain).hasDeletePollMessage();
|
||||
DateTime deletionTime = domain.getDeletionTime();
|
||||
assertThat(getPollMessages("TheRegistrar", deletionTime.minusMinutes(1))).isEmpty();
|
||||
assertThat(getPollMessages("TheRegistrar", deletionTime)).hasSize(1);
|
||||
assertThat(resource.getDeletePollMessage())
|
||||
assertThat(domain.getDeletePollMessage())
|
||||
.isEqualTo(Key.create(getOnlyPollMessage("TheRegistrar")));
|
||||
PollMessage.OneTime deletePollMessage = ofy().load().key(domain.getDeletePollMessage()).now();
|
||||
assertThat(deletePollMessage.getMsg()).isEqualTo(expectedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1069,6 +1074,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
clock.nowUtc().plus(standardDays(15)),
|
||||
"TheRegistrar",
|
||||
null));
|
||||
assertDeletionPollMessageFor(resource, "Deleted by registry administrator.");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1089,6 +1095,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
.and()
|
||||
.hasDeletionTime(clock.nowUtc().plus(standardDays(4)));
|
||||
assertThat(resource.getGracePeriods()).isEmpty();
|
||||
assertDeletionPollMessageFor(resource, "Deleted by registry administrator.");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1115,6 +1122,7 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
clock.nowUtc().plus(standardDays(15)),
|
||||
"TheRegistrar",
|
||||
null));
|
||||
assertDeletionPollMessageFor(resource, "Deleted by registry administrator.");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1128,6 +1136,23 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
|
|||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("generic_success_response.xml"));
|
||||
assertThat(reloadResourceByForeignKey()).isNull();
|
||||
DomainBase resavedDomain = ofy().load().entity(domain).now();
|
||||
assertDeletionPollMessageFor(resavedDomain, "Deleted by registry administrator.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_immediateDelete_withSuperuserAndMetadataExtension() throws Exception {
|
||||
eppRequestSource = EppRequestSource.TOOL;
|
||||
setEppInput(
|
||||
"domain_delete_superuser_and_metadata_extension.xml",
|
||||
ImmutableMap.of("REDEMPTION_GRACE_PERIOD_DAYS", "0", "PENDING_DELETE_DAYS", "0"));
|
||||
setUpSuccessfulTest();
|
||||
clock.advanceOneMilli();
|
||||
runFlowAssertResponse(
|
||||
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("generic_success_response.xml"));
|
||||
assertThat(reloadResourceByForeignKey()).isNull();
|
||||
assertDeletionPollMessageFor(
|
||||
ofy().load().entity(domain).now(), "Deleted by registry administrator: Broke world.");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<delete>
|
||||
<domain:delete
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>example.tld</domain:name>
|
||||
</domain:delete>
|
||||
</delete>
|
||||
<extension>
|
||||
<metadata:metadata xmlns:metadata="urn:google:params:xml:ns:metadata-1.0">
|
||||
<metadata:reason>Deleted by registry administrator: Broke world.</metadata:reason>
|
||||
<metadata:requestedByRegistrar>false</metadata:requestedByRegistrar>
|
||||
</metadata:metadata>
|
||||
<superuser:domainDelete xmlns:superuser="urn:google:params:xml:ns:superuser-1.0">
|
||||
<superuser:redemptionGracePeriodDays>%REDEMPTION_GRACE_PERIOD_DAYS%</superuser:redemptionGracePeriodDays>
|
||||
<superuser:pendingDeleteDays>%PENDING_DELETE_DAYS%</superuser:pendingDeleteDays>
|
||||
</superuser:domainDelete>
|
||||
</extension>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
Loading…
Add table
Add a link
Reference in a new issue