diff --git a/java/google/registry/flows/domain/DomainDeleteFlow.java b/java/google/registry/flows/domain/DomainDeleteFlow.java index 1a92395e0..286ce3a03 100644 --- a/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -72,6 +72,7 @@ import google.registry.model.domain.fee12.FeeDeleteResponseExtensionV12; import google.registry.model.domain.metadata.MetadataExtension; import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.model.domain.secdns.SecDnsCreateExtension; +import google.registry.model.domain.superuser.DomainDeleteSuperuserExtension; import google.registry.model.eppcommon.AuthInfo; import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension; import google.registry.model.eppcommon.StatusValue; @@ -131,7 +132,8 @@ public final class DomainDeleteFlow implements TransactionalFlow { @Override public final EppResponse run() throws EppException { - extensionManager.register(MetadataExtension.class, SecDnsCreateExtension.class); + extensionManager.register( + MetadataExtension.class, SecDnsCreateExtension.class, DomainDeleteSuperuserExtension.class); customLogic.beforeValidation(); extensionManager.validate(); validateClientIsLoggedIn(clientId); @@ -147,6 +149,16 @@ public final class DomainDeleteFlow implements TransactionalFlow { ? ResourceFlowUtils.resolvePendingTransfer( existingDomain, TransferStatus.SERVER_CANCELLED, now) : existingDomain.asBuilder(); + Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength(); + Duration pendingDeleteLength = registry.getPendingDeleteLength(); + DomainDeleteSuperuserExtension domainDeleteSuperuserExtension = + eppInput.getSingleExtension(DomainDeleteSuperuserExtension.class); + if (domainDeleteSuperuserExtension != null) { + redemptionGracePeriodLength = + Duration.standardDays(domainDeleteSuperuserExtension.getRedemptionGracePeriodDays()); + pendingDeleteLength = + Duration.standardDays(domainDeleteSuperuserExtension.getPendingDeleteDays()); + } boolean inAddGracePeriod = existingDomain.getGracePeriodStatuses().contains(GracePeriodStatus.ADD); // If the domain is in the Add Grace Period, we delete it immediately. @@ -155,10 +167,10 @@ public final class DomainDeleteFlow implements TransactionalFlow { inAddGracePeriod ? Duration.ZERO // By default, this should be 30 days of grace, and 5 days of pending delete. - : registry.getRedemptionGracePeriodLength().plus(registry.getPendingDeleteLength()); + : redemptionGracePeriodLength.plus(pendingDeleteLength); HistoryEntry historyEntry = buildHistoryEntry( existingDomain, registry, now, durationUntilDelete, inAddGracePeriod); - if (inAddGracePeriod) { + if (durationUntilDelete.equals(Duration.ZERO)) { builder.setDeletionTime(now).setStatusValues(null); } else { DateTime deletionTime = now.plus(durationUntilDelete); @@ -171,7 +183,7 @@ public final class DomainDeleteFlow implements TransactionalFlow { // billing event because there isn't one for a domain delete. .setGracePeriods(ImmutableSet.of(GracePeriod.createWithoutBillingEvent( GracePeriodStatus.REDEMPTION, - now.plus(registry.getRedemptionGracePeriodLength()), + now.plus(redemptionGracePeriodLength), clientId))) .setDeletePollMessage(Key.create(deletePollMessage)); // Note: The expiration time is unchanged, so if it's before the new deletion time, there will diff --git a/java/google/registry/model/domain/superuser/DomainDeleteSuperuserExtension.java b/java/google/registry/model/domain/superuser/DomainDeleteSuperuserExtension.java new file mode 100644 index 000000000..48d69313d --- /dev/null +++ b/java/google/registry/model/domain/superuser/DomainDeleteSuperuserExtension.java @@ -0,0 +1,36 @@ +// Copyright 2017 The Nomulus Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package google.registry.model.domain.superuser; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** A superuser extension that may be present on domain delete commands. */ +@XmlRootElement(name = "domainDelete") +public class DomainDeleteSuperuserExtension extends SuperuserExtension { + @XmlElement(name = "redemptionGracePeriodDays") + int redemptionGracePeriodDays; + + @XmlElement(name = "pendingDeleteDays") + int pendingDeleteDays; + + public int getRedemptionGracePeriodDays() { + return redemptionGracePeriodDays; + } + + public int getPendingDeleteDays() { + return pendingDeleteDays; + } +} diff --git a/java/google/registry/model/eppinput/EppInput.java b/java/google/registry/model/eppinput/EppInput.java index 010e7d894..8ac861846 100644 --- a/java/google/registry/model/eppinput/EppInput.java +++ b/java/google/registry/model/eppinput/EppInput.java @@ -51,6 +51,7 @@ import google.registry.model.domain.metadata.MetadataExtension; import google.registry.model.domain.rgp.RgpUpdateExtension; import google.registry.model.domain.secdns.SecDnsCreateExtension; import google.registry.model.domain.secdns.SecDnsUpdateExtension; +import google.registry.model.domain.superuser.DomainDeleteSuperuserExtension; import google.registry.model.domain.superuser.DomainTransferRequestSuperuserExtension; import google.registry.model.eppinput.ResourceCommand.ResourceCheck; import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; @@ -347,7 +348,8 @@ public class EppInput extends ImmutableObject { @XmlElementRef(type = RgpUpdateExtension.class), @XmlElementRef(type = SecDnsCreateExtension.class), @XmlElementRef(type = SecDnsUpdateExtension.class), - @XmlElementRef(type = DomainTransferRequestSuperuserExtension.class) }) + @XmlElementRef(type = DomainTransferRequestSuperuserExtension.class), + @XmlElementRef(type = DomainDeleteSuperuserExtension.class) }) @XmlElementWrapper List extension; diff --git a/java/google/registry/xml/xsd/superuser.xsd b/java/google/registry/xml/xsd/superuser.xsd index 8d4660349..369a5746d 100644 --- a/java/google/registry/xml/xsd/superuser.xsd +++ b/java/google/registry/xml/xsd/superuser.xsd @@ -38,4 +38,13 @@ + + + + + + + + + diff --git a/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java b/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java index 5359ac2bd..53a9c320b 100644 --- a/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainDeleteFlowTest.java @@ -952,4 +952,89 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase + + + + example.tld + + + + + %REDEMPTION_GRACE_PERIOD_DAYS% + %PENDING_DELETE_DAYS% + + + ABC-12345 + +