diff --git a/java/google/registry/batch/DeleteContactsAndHostsAction.java b/java/google/registry/batch/DeleteContactsAndHostsAction.java index af2efab63..11b27b761 100644 --- a/java/google/registry/batch/DeleteContactsAndHostsAction.java +++ b/java/google/registry/batch/DeleteContactsAndHostsAction.java @@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.math.IntMath.divide; import static com.googlecode.objectify.Key.getKind; -import static google.registry.flows.ResourceFlowUtils.createResolvedTransferData; +import static google.registry.flows.ResourceFlowUtils.denyPendingTransfer; import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete; import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime; import static google.registry.flows.async.AsyncFlowEnqueuer.PARAM_CLIENT_TRANSACTION_ID; @@ -373,12 +373,12 @@ public class DeleteContactsAndHostsAction implements Runnable { EppResource.Builder resourceToSaveBuilder; if (resource instanceof ContactResource) { ContactResource contact = (ContactResource) resource; - ContactResource.Builder contactToSaveBuilder = contact.asBuilder(); + // Handle pending transfers on contact deletion. if (contact.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) { - contactToSaveBuilder = contactToSaveBuilder.setTransferData(createResolvedTransferData( - contact.getTransferData(), TransferStatus.SERVER_CANCELLED, now)); + contact = denyPendingTransfer(contact, TransferStatus.SERVER_CANCELLED, now); } - resourceToSaveBuilder = contactToSaveBuilder.wipeOut(); + // Wipe out PII on contact deletion. + resourceToSaveBuilder = contact.asBuilder().wipeOut(); } else { resourceToSaveBuilder = resource.asBuilder(); } diff --git a/java/google/registry/flows/ResourceFlowUtils.java b/java/google/registry/flows/ResourceFlowUtils.java index 40b9d680d..a26fef231 100644 --- a/java/google/registry/flows/ResourceFlowUtils.java +++ b/java/google/registry/flows/ResourceFlowUtils.java @@ -206,25 +206,6 @@ public final class ResourceFlowUtils { } } - /** - * Create a {@link TransferData} object representing a resolved transfer. - * - *

This clears all the server-approve fields on the {@link TransferData}, sets the status - * field, and sets the expiration time of the last pending transfer to now. - */ - public static TransferData createResolvedTransferData( - TransferData oldTransferData, TransferStatus transferStatus, DateTime now) { - checkArgument(!oldTransferData.equals(TransferData.EMPTY), "No old transfer to resolve."); - return oldTransferData.asBuilder() - .setServerApproveEntities(null) - .setServerApproveBillingEvent(null) - .setServerApproveAutorenewEvent(null) - .setServerApproveAutorenewPollMessage(null) - .setTransferStatus(transferStatus) - .setPendingTransferExpirationTime(checkNotNull(now)) - .build(); - } - /** * Turn a resource into a builder with its pending transfer resolved. * @@ -232,18 +213,29 @@ public final class ResourceFlowUtils { * TransferStatus}, clears all the server-approve fields on the {@link TransferData}, and sets the * expiration time of the last pending transfer to now. */ - @SuppressWarnings("unchecked") - public static < + private static < R extends EppResource & ResourceWithTransferData, B extends EppResource.Builder & BuilderWithTransferData> B resolvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) { - checkState( + checkArgument( resource.getStatusValues().contains(StatusValue.PENDING_TRANSFER), "Resource is not in pending transfer status."); - return ((B) resource.asBuilder()) + checkArgument( + !TransferData.EMPTY.equals(resource.getTransferData()), + "No old transfer data to resolve."); + @SuppressWarnings("unchecked") + B builder = (B) resource.asBuilder(); + return builder .removeStatusValue(StatusValue.PENDING_TRANSFER) .setTransferData( - createResolvedTransferData(resource.getTransferData(), transferStatus, now)); + resource.getTransferData().asBuilder() + .setServerApproveEntities(null) + .setServerApproveBillingEvent(null) + .setServerApproveAutorenewEvent(null) + .setServerApproveAutorenewPollMessage(null) + .setTransferStatus(transferStatus) + .setPendingTransferExpirationTime(checkNotNull(now)) + .build()); } /** @@ -258,6 +250,7 @@ public final class ResourceFlowUtils { R extends EppResource & ResourceWithTransferData, B extends Builder & BuilderWithTransferData> R approvePendingTransfer(R resource, TransferStatus transferStatus, DateTime now) { + checkArgument(transferStatus.isApproved(), "Not an approval transfer status"); B builder = ResourceFlowUtils.resolvePendingTransfer(resource, transferStatus, now); return builder .setLastTransferTime(now) @@ -274,6 +267,7 @@ public final class ResourceFlowUtils { */ public static R denyPendingTransfer( R resource, TransferStatus transferStatus, DateTime now) { + checkArgument(transferStatus.isDenied(), "Not a denial transfer status"); return resolvePendingTransfer(resource, transferStatus, now).build(); } diff --git a/java/google/registry/flows/domain/DomainDeleteFlow.java b/java/google/registry/flows/domain/DomainDeleteFlow.java index 286ce3a03..83263be5f 100644 --- a/java/google/registry/flows/domain/DomainDeleteFlow.java +++ b/java/google/registry/flows/domain/DomainDeleteFlow.java @@ -17,6 +17,7 @@ package google.registry.flows.domain; import static com.google.common.base.Preconditions.checkNotNull; import static google.registry.flows.FlowUtils.persistEntityChanges; import static google.registry.flows.FlowUtils.validateClientIsLoggedIn; +import static google.registry.flows.ResourceFlowUtils.denyPendingTransfer; import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete; import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence; import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime; @@ -48,7 +49,6 @@ import google.registry.flows.ExtensionManager; import google.registry.flows.FlowModule.ClientId; import google.registry.flows.FlowModule.Superuser; import google.registry.flows.FlowModule.TargetId; -import google.registry.flows.ResourceFlowUtils; import google.registry.flows.SessionMetadata; import google.registry.flows.TransactionalFlow; import google.registry.flows.annotations.ReportingSpec; @@ -145,10 +145,13 @@ public final class DomainDeleteFlow implements TransactionalFlow { customLogic.afterValidation( AfterValidationParameters.newBuilder().setExistingDomain(existingDomain).build()); ImmutableSet.Builder entitiesToSave = new ImmutableSet.Builder<>(); - Builder builder = existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER) - ? ResourceFlowUtils.resolvePendingTransfer( - existingDomain, TransferStatus.SERVER_CANCELLED, now) - : existingDomain.asBuilder(); + Builder builder; + if (existingDomain.getStatusValues().contains(StatusValue.PENDING_TRANSFER)) { + builder = + denyPendingTransfer(existingDomain, TransferStatus.SERVER_CANCELLED, now).asBuilder(); + } else { + builder = existingDomain.asBuilder(); + } Duration redemptionGracePeriodLength = registry.getRedemptionGracePeriodLength(); Duration pendingDeleteLength = registry.getPendingDeleteLength(); DomainDeleteSuperuserExtension domainDeleteSuperuserExtension = diff --git a/java/google/registry/model/transfer/TransferStatus.java b/java/google/registry/model/transfer/TransferStatus.java index 5633f2efe..936d8f600 100644 --- a/java/google/registry/model/transfer/TransferStatus.java +++ b/java/google/registry/model/transfer/TransferStatus.java @@ -54,4 +54,10 @@ public enum TransferStatus { public boolean isApproved() { return this.equals(CLIENT_APPROVED) || this.equals(SERVER_APPROVED); } + + public boolean isDenied() { + return this.equals(CLIENT_CANCELLED) + || this.equals(CLIENT_REJECTED) + || this.equals(SERVER_CANCELLED); + } }