diff --git a/java/google/registry/flows/OwnedResourceMutatePendingTransferFlow.java b/java/google/registry/flows/OwnedResourceMutatePendingTransferFlow.java deleted file mode 100644 index f00e07f1f..000000000 --- a/java/google/registry/flows/OwnedResourceMutatePendingTransferFlow.java +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership; - -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; - -/** - * An EPP flow that acts on an owned resource with a pending transfer on it. - * - * @param the resource type being manipulated - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class OwnedResourceMutatePendingTransferFlow - , C extends SingleResourceCommand> - extends ResourceMutatePendingTransferFlow { - - /** Fail if this command isn't coming from the registrar that currently owns the resource. */ - @Override - protected final void verifyPendingTransferMutationAllowed() throws EppException { - verifyResourceOwnership(getClientId(), existingResource); - verifyOwnedResourcePendingTransferMutationAllowed(); - } - - @SuppressWarnings("unused") - protected void verifyOwnedResourcePendingTransferMutationAllowed() throws EppException {} -} diff --git a/java/google/registry/flows/ResourceAsyncDeleteFlow.java b/java/google/registry/flows/ResourceAsyncDeleteFlow.java deleted file mode 100644 index d5777ac63..000000000 --- a/java/google/registry/flows/ResourceAsyncDeleteFlow.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; -import static google.registry.model.ofy.ObjectifyService.ofy; - -import com.googlecode.objectify.Key; -import com.googlecode.objectify.Work; -import google.registry.flows.EppException.AssociationProhibitsOperationException; -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppcommon.StatusValue; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.Result.Code; -import google.registry.model.index.ForeignKeyIndex; - -/** - * An EPP flow that deletes a resource asynchronously (i.e. via mapreduce). - * - * @param the resource type being changed - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceAsyncDeleteFlow - , C extends SingleResourceCommand> - extends ResourceDeleteFlow { - - @Override - public void failfast() throws ResourceToDeleteIsReferencedException { - // Enter a transactionless context briefly. - boolean isLinked = ofy().doTransactionless(new Work() { - @Override - public Boolean run() { - ForeignKeyIndex fki = ForeignKeyIndex.load(resourceClass, targetId, now); - if (fki == null) { - // Don't failfast on non-existence. We could, but that would duplicate code paths in a way - // that would be hard to reason about, and there's no real gain in doing so. - return false; - } - return isLinkedForFailfast(fki.getResourceKey()); - } - }); - if (isLinked) { - throw new ResourceToDeleteIsReferencedException(); - } - } - - /** Subclasses must override this to check if the supplied key has incoming links. */ - protected abstract boolean isLinkedForFailfast(Key key); - - @Override - protected final R createOrMutateResource() { - @SuppressWarnings("unchecked") - B builder = (B) existingResource.asBuilder().addStatusValue(StatusValue.PENDING_DELETE); - return builder.build(); - } - - /** Subclasses can override this to return a different success result code. */ - @Override - protected Code getDeleteResultCode() { - return SUCCESS_WITH_ACTION_PENDING; - } - - /** Resource to be deleted has active incoming references. */ - public static class ResourceToDeleteIsReferencedException - extends AssociationProhibitsOperationException { - public ResourceToDeleteIsReferencedException() { - super("Resource to be deleted has active incoming references"); - } - } -} diff --git a/java/google/registry/flows/ResourceCheckFlow.java b/java/google/registry/flows/ResourceCheckFlow.java deleted file mode 100644 index 9cd1c0fcf..000000000 --- a/java/google/registry/flows/ResourceCheckFlow.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.model.eppoutput.Result.Code.SUCCESS; - -import com.google.common.collect.ImmutableList; -import google.registry.config.RegistryEnvironment; -import google.registry.flows.EppException.ParameterValuePolicyErrorException; -import google.registry.model.EppResource; -import google.registry.model.eppinput.ResourceCommand.ResourceCheck; -import google.registry.model.eppoutput.CheckData; -import google.registry.model.eppoutput.EppOutput; -import google.registry.model.eppoutput.EppResponse.ResponseExtension; -import java.util.List; - -/** - * An EPP flow that checks whether resources can be provisioned. - * - * @param the resource type being manipulated - * @param the overall command type doing the manipulation. - */ -public abstract class ResourceCheckFlow - extends ResourceFlow { - - protected List targetIds; - - @Override - protected final void initResourceFlow() throws EppException { - this.targetIds = command.getTargetIds(); - initCheckResourceFlow(); - } - - @Override - protected final EppOutput runResourceFlow() throws EppException { - return createOutput( - SUCCESS, - getCheckData(), - getResponseExtensions()); - } - - @Override - protected final void verifyIsAllowed() throws EppException { - if (targetIds.size() > RegistryEnvironment.get().config().getMaxChecks()) { - throw new TooManyResourceChecksException(); - } - } - - @SuppressWarnings("unused") - protected void initCheckResourceFlow() throws EppException {} - - /** Subclasses must implement this to return the check data. */ - protected abstract CheckData getCheckData(); - - /** Subclasses may override this to return extensions. */ - @SuppressWarnings("unused") - protected ImmutableList getResponseExtensions() throws EppException { - return null; - } - - /** Too many resource checks requested in one check command. */ - public static class TooManyResourceChecksException extends ParameterValuePolicyErrorException { - public TooManyResourceChecksException() { - super(String.format( - "No more than %s resources may be checked at a time", - RegistryEnvironment.get().config().getMaxChecks())); - } - } -} - diff --git a/java/google/registry/flows/ResourceDeleteFlow.java b/java/google/registry/flows/ResourceDeleteFlow.java deleted file mode 100644 index 3de087ff5..000000000 --- a/java/google/registry/flows/ResourceDeleteFlow.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.model.eppoutput.Result.Code.SUCCESS; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import google.registry.model.EppResource; -import google.registry.model.eppcommon.StatusValue; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.EppOutput; -import google.registry.model.eppoutput.EppResponse.ResponseExtension; -import google.registry.model.eppoutput.Result.Code; -import java.util.Set; -import javax.annotation.Nullable; - -/** - * An EPP flow that deletes an {@link EppResource}. - * - * @param the resource type being changed - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceDeleteFlow - extends OwnedResourceMutateFlow { - - private static final Set DELETE_DISALLOWED_STATUSES = ImmutableSet.of( - StatusValue.LINKED, - StatusValue.CLIENT_DELETE_PROHIBITED, - StatusValue.PENDING_DELETE, - StatusValue.SERVER_DELETE_PROHIBITED); - - /** This is intentionally non-final so that subclasses can override the disallowed statuses. */ - @Override - protected Set getDisallowedStatuses() { - return DELETE_DISALLOWED_STATUSES; - } - - @Override - protected final EppOutput getOutput() { - return createOutput(getDeleteResultCode(), null, getDeleteResponseExtensions()); - } - - /** Subclasses can override this to return a different success result code. */ - protected Code getDeleteResultCode() { - return SUCCESS; - } - - /** Subclasses can override this to return response extensions. */ - @Nullable - protected ImmutableList getDeleteResponseExtensions() { - return null; - } -} diff --git a/java/google/registry/flows/ResourceInfoFlow.java b/java/google/registry/flows/ResourceInfoFlow.java deleted file mode 100644 index a2926f325..000000000 --- a/java/google/registry/flows/ResourceInfoFlow.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.model.EppResourceUtils.cloneResourceWithLinkedStatus; -import static google.registry.model.eppoutput.Result.Code.SUCCESS; - -import com.google.common.collect.ImmutableList; -import google.registry.model.EppResource; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.EppOutput; -import google.registry.model.eppoutput.EppResponse.ResponseData; -import google.registry.model.eppoutput.EppResponse.ResponseExtension; - -/** - * An EPP flow that reads a storable resource. - * - * @param the resource type being manipulated - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceInfoFlow - extends ResourceQueryFlow { - @Override - public EppOutput runResourceFlow() throws EppException { - return createOutput(SUCCESS, getResourceInfo(), getResponseExtensions()); - } - - @SuppressWarnings("unused") - protected ResponseData getResourceInfo() throws EppException { - return cloneResourceWithLinkedStatus(existingResource, now); - } - - @SuppressWarnings("unused") - protected ImmutableList getResponseExtensions() throws EppException { - return null; - } -} diff --git a/java/google/registry/flows/ResourceMutatePendingTransferFlow.java b/java/google/registry/flows/ResourceMutatePendingTransferFlow.java deleted file mode 100644 index aabd98bb0..000000000 --- a/java/google/registry/flows/ResourceMutatePendingTransferFlow.java +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.model.eppoutput.Result.Code.SUCCESS; -import static google.registry.model.ofy.ObjectifyService.ofy; - -import google.registry.flows.EppException.ObjectNotPendingTransferException; -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppcommon.StatusValue; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.EppOutput; -import google.registry.model.transfer.TransferData; -import google.registry.model.transfer.TransferStatus; - -/** - * An EPP flow that acts on a resource with a pending transfer on it. - * - * @param the resource type being changed - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceMutatePendingTransferFlow - , C extends SingleResourceCommand> - extends ResourceTransferFlow { - - /** Fail if object doesn't have a pending transfer, or if authinfo doesn't match. */ - @Override - protected final void verifyMutationAllowed() throws EppException { - if (existingResource.getTransferData().getTransferStatus() != TransferStatus.PENDING) { - throw new NotPendingTransferException(targetId); - } - verifyPendingTransferMutationAllowed(); - } - - @SuppressWarnings("unused") - protected void verifyPendingTransferMutationAllowed() throws EppException {} - - @Override - @SuppressWarnings("unchecked") - protected final R createOrMutateResource() { - TransferData transferData = existingResource.getTransferData(); - B builder = (B) existingResource.asBuilder() - .removeStatusValue(StatusValue.PENDING_TRANSFER) - .setTransferData(transferData.asBuilder() - .setTransferStatus(getTransferStatus()) - .setPendingTransferExpirationTime(now) - .setExtendedRegistrationYears(null) - .setServerApproveEntities(null) - .setServerApproveBillingEvent(null) - .setServerApproveAutorenewEvent(null) - .setServerApproveAutorenewPollMessage(null) - .build()); - setTransferMutateProperties(builder); - return builder.build(); - } - - /** Get the new transfer status to set on the resource (and subordinates) after the flow. */ - protected abstract TransferStatus getTransferStatus(); - - /** Set any resource-specific properties for the pending-transfer mutation. */ - protected void setTransferMutateProperties(@SuppressWarnings("unused") B builder) {} - - /** - * Delete the billing event and poll messages that were written in case the transfer would have - * been implicitly server approved. - */ - @Override - protected final void modifyRelatedResources() throws EppException { - modifyRelatedResourcesForMutateTransfer(); - ofy().delete().keys(existingResource.getTransferData().getServerApproveEntities()); - } - - /** Subclasses can override this to make any other model changes that are implied by this flow. */ - @SuppressWarnings("unused") - protected void modifyRelatedResourcesForMutateTransfer() throws EppException {} - - @Override - protected final EppOutput getOutput() throws EppException { - return createOutput( - SUCCESS, createTransferResponse(newResource, newResource.getTransferData(), now)); - } - - /** The resource does not have a pending transfer. */ - public static class NotPendingTransferException extends ObjectNotPendingTransferException { - public NotPendingTransferException(String objectId) { - super(objectId); - } - } -} diff --git a/java/google/registry/flows/ResourceSyncDeleteFlow.java b/java/google/registry/flows/ResourceSyncDeleteFlow.java deleted file mode 100644 index 31171ae92..000000000 --- a/java/google/registry/flows/ResourceSyncDeleteFlow.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.handlePendingTransferOnDelete; -import static google.registry.flows.ResourceFlowUtils.prepareDeletedResourceAsBuilder; -import static google.registry.flows.ResourceFlowUtils.updateForeignKeyIndexDeletionTime; - -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.index.ForeignKeyIndex; - -/** - * An EPP flow that deletes a resource synchronously. - * - * @param the resource type being changed - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceSyncDeleteFlow - , C extends SingleResourceCommand> - extends ResourceDeleteFlow { - - @Override - @SuppressWarnings("unchecked") - protected final R createOrMutateResource() throws EppException { - B builder = (B) prepareDeletedResourceAsBuilder(existingResource, now); - setDeleteProperties(builder); - return builder.build(); - } - - /** Update the relevant {@link ForeignKeyIndex} to cache the new deletion time. */ - @Override - protected final void modifyRelatedResources() throws EppException { - updateForeignKeyIndexDeletionTime(newResource); - handlePendingTransferOnDelete(existingResource, newResource, now, historyEntry); - modifySyncDeleteRelatedResources(); - } - - /** Set any resource-specific properties before deleting. */ - @SuppressWarnings("unused") - protected void setDeleteProperties(B builder) throws EppException {} - - /** Modify any other resources that need to be informed of this delete. */ - protected void modifySyncDeleteRelatedResources() {} -} diff --git a/java/google/registry/flows/ResourceTransferApproveFlow.java b/java/google/registry/flows/ResourceTransferApproveFlow.java deleted file mode 100644 index 33a1e5c6b..000000000 --- a/java/google/registry/flows/ResourceTransferApproveFlow.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createPendingTransferNotificationResponse; -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.model.ofy.ObjectifyService.ofy; - -import com.google.common.collect.ImmutableList; -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.poll.PollMessage; -import google.registry.model.transfer.TransferData; -import google.registry.model.transfer.TransferStatus; - -/** - * An EPP flow that approves a transfer on a resource. - * - * @param the resource type being manipulated - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceTransferApproveFlow - , C extends SingleResourceCommand> - extends OwnedResourceMutatePendingTransferFlow { - - @Override - protected final TransferStatus getTransferStatus() { - return TransferStatus.CLIENT_APPROVED; - } - - @Override - protected final void setTransferMutateProperties(B builder) { - builder.setLastTransferTime(now) - .setCurrentSponsorClientId(existingResource.getTransferData().getGainingClientId()); - setTransferApproveProperties(builder); - } - - protected void setTransferApproveProperties(@SuppressWarnings("unused") B builder) {} - - @Override - protected void modifyRelatedResourcesForMutateTransfer() throws EppException { - // Create a poll message for the gaining client. - TransferData oldTransferData = existingResource.getTransferData(); - ofy().save().entity(new PollMessage.OneTime.Builder() - .setClientId(oldTransferData.getGainingClientId()) - .setEventTime(now) - .setMsg(TransferStatus.CLIENT_APPROVED.getMessage()) - .setResponseData(ImmutableList.of( - createTransferResponse(newResource, newResource.getTransferData(), now), - createPendingTransferNotificationResponse( - existingResource, oldTransferData.getTransferRequestTrid(), true, now))) - .setParent(historyEntry) - .build()); - modifyRelatedResourcesForTransferApprove(); - } - - /** Subclasses can override this to modify other transfer-related resources. */ - protected void modifyRelatedResourcesForTransferApprove() {} -} diff --git a/java/google/registry/flows/ResourceTransferCancelFlow.java b/java/google/registry/flows/ResourceTransferCancelFlow.java deleted file mode 100644 index 9925482ba..000000000 --- a/java/google/registry/flows/ResourceTransferCancelFlow.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.model.ofy.ObjectifyService.ofy; - -import com.google.common.collect.ImmutableList; -import google.registry.flows.EppException.AuthorizationErrorException; -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.poll.PollMessage; -import google.registry.model.transfer.TransferStatus; - -/** - * An EPP flow that cancels a transfer on a resource. - * - * @param the resource type being manipulated - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceTransferCancelFlow - , C extends SingleResourceCommand> - extends ResourceMutatePendingTransferFlow { - - /** Verify that this is the correct client to cancel this pending transfer. */ - @Override - protected final void verifyPendingTransferMutationAllowed() throws EppException { - if (!getClientId().equals(existingResource.getTransferData().getGainingClientId())) { - throw new NotTransferInitiatorException(); - } - verifyTransferCancelMutationAllowed(); - } - - @SuppressWarnings("unused") - protected void verifyTransferCancelMutationAllowed() throws EppException {} - - @Override - protected void modifyRelatedResourcesForMutateTransfer() throws EppException { - ofy().save().entity(new PollMessage.OneTime.Builder() - .setClientId(existingResource.getTransferData().getLosingClientId()) - .setEventTime(now) - .setMsg(TransferStatus.CLIENT_CANCELLED.getMessage()) - .setResponseData(ImmutableList.of( - createTransferResponse(newResource, newResource.getTransferData(), now))) - .setParent(historyEntry) - .build()); - modifyRelatedResourcesForTransferCancel(); - } - - /** Subclasses can override this to modify other cancellation-related resources. */ - protected void modifyRelatedResourcesForTransferCancel() {} - - @Override - protected final TransferStatus getTransferStatus() { - return TransferStatus.CLIENT_CANCELLED; - } - - /** Registrar is not the initiator of this transfer. */ - public static class NotTransferInitiatorException extends AuthorizationErrorException { - public NotTransferInitiatorException() { - super("Registrar is not the initiator of this transfer"); - } - } -} diff --git a/java/google/registry/flows/ResourceTransferFlow.java b/java/google/registry/flows/ResourceTransferFlow.java deleted file mode 100644 index ad879fb65..000000000 --- a/java/google/registry/flows/ResourceTransferFlow.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import google.registry.model.EppResource; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; - -/** - * An EPP flow that involves a transfer on a resource. - * - * @param the resource type being manipulated - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceTransferFlow - extends ResourceMutateFlow {} diff --git a/java/google/registry/flows/ResourceTransferQueryFlow.java b/java/google/registry/flows/ResourceTransferQueryFlow.java deleted file mode 100644 index d55b0a523..000000000 --- a/java/google/registry/flows/ResourceTransferQueryFlow.java +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.model.eppoutput.Result.Code.SUCCESS; - -import google.registry.flows.EppException.AuthorizationErrorException; -import google.registry.flows.EppException.CommandUseErrorException; -import google.registry.model.EppResource; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.EppOutput; - -/** - * An EPP flow that queries the state of a pending transfer on a resource. - * - * @param the resource type being manipulated - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceTransferQueryFlow extends ResourceQueryFlow { - - @Override - protected final void verifyQueryIsAllowed() throws EppException { - // Most of the fields on the transfer response are required, so there's no way to return valid - // XML if the object has never been transferred (and hence the fields aren't populated). - if (existingResource.getTransferData().getTransferStatus() == null) { - throw new NoTransferHistoryToQueryException(); - } - - // Note that the authorization info on the command (if present) has already been verified by the - // parent class. If it's present, then the other checks are unnecessary. - if (command.getAuthInfo() == null && - !getClientId().equals(existingResource.getTransferData().getGainingClientId()) && - !getClientId().equals(existingResource.getTransferData().getLosingClientId())) { - throw new NotAuthorizedToViewTransferException(); - } - } - - @Override - public final EppOutput runResourceFlow() throws EppException { - return createOutput( - SUCCESS, createTransferResponse(existingResource, existingResource.getTransferData(), now)); - } - - /** Registrar is not authorized to view transfer status. */ - public static class NotAuthorizedToViewTransferException - extends AuthorizationErrorException { - public NotAuthorizedToViewTransferException() { - super("Registrar is not authorized to view transfer status"); - } - } - - /** Object has no transfer history. */ - public static class NoTransferHistoryToQueryException extends CommandUseErrorException { - public NoTransferHistoryToQueryException() { - super("Object has no transfer history"); - } - } -} diff --git a/java/google/registry/flows/ResourceTransferRejectFlow.java b/java/google/registry/flows/ResourceTransferRejectFlow.java deleted file mode 100644 index c6fb42fa7..000000000 --- a/java/google/registry/flows/ResourceTransferRejectFlow.java +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createPendingTransferNotificationResponse; -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.model.ofy.ObjectifyService.ofy; - -import com.google.common.collect.ImmutableList; -import google.registry.model.EppResource; -import google.registry.model.EppResource.Builder; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.poll.PollMessage; -import google.registry.model.transfer.TransferData; -import google.registry.model.transfer.TransferStatus; - -/** - * An EPP flow that rejects a transfer on a resource. - * - * @param the resource type being manipulated - * @param a builder for the resource - * @param the command type, marshalled directly from the epp xml - */ -public abstract class ResourceTransferRejectFlow - , C extends SingleResourceCommand> - extends OwnedResourceMutatePendingTransferFlow { - - @Override - protected final TransferStatus getTransferStatus() { - return TransferStatus.CLIENT_REJECTED; - } - - @Override - protected void modifyRelatedResourcesForMutateTransfer() throws EppException { - TransferData oldTransferData = existingResource.getTransferData(); - ofy().save().entity(new PollMessage.OneTime.Builder() - .setClientId(oldTransferData.getGainingClientId()) - .setEventTime(now) - .setMsg(TransferStatus.CLIENT_REJECTED.getMessage()) - .setResponseData(ImmutableList.of( - createTransferResponse(newResource, newResource.getTransferData(), now), - createPendingTransferNotificationResponse( - existingResource, oldTransferData.getTransferRequestTrid(), false, now))) - .setParent(historyEntry) - .build()); - modifyRelatedResourcesForTransferReject(); - } - - /** Subclasses can override this to modify other rejection-related resources. */ - protected void modifyRelatedResourcesForTransferReject() {} -} diff --git a/java/google/registry/flows/ResourceTransferRequestFlow.java b/java/google/registry/flows/ResourceTransferRequestFlow.java deleted file mode 100644 index e9400be74..000000000 --- a/java/google/registry/flows/ResourceTransferRequestFlow.java +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows; - -import static google.registry.flows.ResourceFlowUtils.createPendingTransferNotificationResponse; -import static google.registry.flows.ResourceFlowUtils.createTransferResponse; -import static google.registry.flows.ResourceFlowUtils.verifyAuthInfoForResource; -import static google.registry.model.eppoutput.Result.Code.SUCCESS_WITH_ACTION_PENDING; -import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.util.CollectionUtils.union; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.googlecode.objectify.Key; -import google.registry.flows.EppException.AuthorizationErrorException; -import google.registry.flows.EppException.CommandUseErrorException; -import google.registry.flows.EppException.ObjectPendingTransferException; -import google.registry.model.EppResource; -import google.registry.model.eppcommon.StatusValue; -import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand; -import google.registry.model.eppoutput.EppOutput; -import google.registry.model.eppoutput.EppResponse.ResponseData; -import google.registry.model.eppoutput.EppResponse.ResponseExtension; -import google.registry.model.poll.PollMessage; -import google.registry.model.transfer.TransferData; -import google.registry.model.transfer.TransferData.TransferServerApproveEntity; -import google.registry.model.transfer.TransferStatus; -import java.util.Set; -import org.joda.time.DateTime; -import org.joda.time.Duration; - -/** - * An EPP flow that requests a transfer on a resource. - * - * @param the resource type being manipulated - * @param the command type, marshalled directly from the epp xml - */ - public abstract class ResourceTransferRequestFlow - extends ResourceTransferFlow { - - private static final Set TRANSFER_DISALLOWED_STATUSES = ImmutableSet.of( - StatusValue.CLIENT_TRANSFER_PROHIBITED, - StatusValue.PENDING_DELETE, - StatusValue.SERVER_TRANSFER_PROHIBITED); - - private DateTime transferExpirationTime; - - /** Helper class to identify the two clients. */ - protected abstract static class Client { - public abstract String getId(); - } - - /** The gaining client. */ - protected Client gainingClient = new Client() { - @Override - public String getId() { - return getClientId(); - }}; - - /** The losing client. */ - protected Client losingClient = new Client() { - @Override - public String getId() { - return existingResource.getCurrentSponsorClientId(); - }}; - - @Override - protected final void initResourceCreateOrMutateFlow() throws EppException { - initResourceTransferRequestFlow(); - } - - protected abstract Duration getAutomaticTransferLength(); - - @Override - protected final void verifyMutationAllowed() throws EppException { - // Verify that the resource does not already have a pending transfer. - if (TransferStatus.PENDING.equals(existingResource.getTransferData().getTransferStatus())) { - throw new AlreadyPendingTransferException(targetId); - } - // Verify that this client doesn't already sponsor this resource. - if (gainingClient.getId().equals(losingClient.getId())) { - throw new ObjectAlreadySponsoredException(); - } - if (command.getAuthInfo() == null) { - throw new MissingTransferRequestAuthInfoException(); - } - verifyAuthInfoForResource(command.getAuthInfo(), existingResource); - verifyTransferRequestIsAllowed(); - } - - private TransferData.Builder - createTransferDataBuilder(TransferStatus transferStatus) throws EppException { - TransferData.Builder builder = new TransferData.Builder() - .setGainingClientId(gainingClient.getId()) - .setTransferRequestTime(now) - .setLosingClientId(losingClient.getId()) - .setPendingTransferExpirationTime(transferExpirationTime) - .setTransferRequestTrid(trid) - .setTransferStatus(transferStatus); - setTransferDataProperties(builder); - return builder; - } - - private PollMessage createPollMessage( - Client client, TransferStatus transferStatus, DateTime eventTime) throws EppException { - ImmutableList.Builder responseData = new ImmutableList.Builder<>(); - responseData.add(createTransferResponse( - existingResource, createTransferDataBuilder(transferStatus).build(), now)); - if (client.getId().equals(gainingClient.getId())) { - responseData.add(createPendingTransferNotificationResponse( - existingResource, trid, true, now)); - } - return new PollMessage.OneTime.Builder() - .setClientId(client.getId()) - .setEventTime(eventTime) - .setMsg(transferStatus.getMessage()) - .setResponseData(responseData.build()) - .setParent(historyEntry) - .build(); - } - - @Override - @SuppressWarnings("unchecked") - protected final R createOrMutateResource() throws EppException { - // Figure out transfer expiration time once we've verified that the existingResource does in - // fact exist (otherwise we won't know which TLD to get this figure off of). - transferExpirationTime = now.plus(getAutomaticTransferLength()); - // When a transfer is requested, a poll message is created to notify the losing registrar. - PollMessage requestPollMessage = createPollMessage(losingClient, TransferStatus.PENDING, now); - // If the transfer is server approved, this message will be sent to the gaining registrar. */ - PollMessage serverApproveGainingPollMessage = - createPollMessage(gainingClient, TransferStatus.SERVER_APPROVED, transferExpirationTime); - // If the transfer is server approved, this message will be sent to the losing registrar. */ - PollMessage serverApproveLosingPollMessage = - createPollMessage(losingClient, TransferStatus.SERVER_APPROVED, transferExpirationTime); - ofy().save().entities( - requestPollMessage, serverApproveGainingPollMessage, serverApproveLosingPollMessage); - return (R) existingResource.asBuilder() - .setTransferData(createTransferDataBuilder(TransferStatus.PENDING) - .setServerApproveEntities(union( - getTransferServerApproveEntities(), - Key.create(serverApproveGainingPollMessage), - Key.create(serverApproveLosingPollMessage))) - .build()) - .addStatusValue(StatusValue.PENDING_TRANSFER) - .build(); - } - - /** Subclasses can override this to do further initialization. */ - protected void initResourceTransferRequestFlow() throws EppException {} - - /** - * Subclasses can override this to return the keys of any entities that need to be deleted if the - * transfer ends in any state other than SERVER_APPROVED. - */ - protected Set> getTransferServerApproveEntities() { - return ImmutableSet.of(); - } - - /** Check resource-specific invariants before allowing the transfer request to proceed. */ - @SuppressWarnings("unused") - protected void verifyTransferRequestIsAllowed() throws EppException {} - - /** Subclasses can override this to modify fields on the transfer data builder. */ - @SuppressWarnings("unused") - protected void setTransferDataProperties(TransferData.Builder builder) throws EppException {} - - @Override - protected final EppOutput getOutput() throws EppException { - return createOutput( - SUCCESS_WITH_ACTION_PENDING, - createTransferResponse(newResource, newResource.getTransferData(), now), - getTransferResponseExtensions()); - } - - /** Subclasses can override this to return response extensions. */ - protected ImmutableList getTransferResponseExtensions() { - return null; - } - - @Override - protected final Set getDisallowedStatuses() { - return TRANSFER_DISALLOWED_STATUSES; - } - - /** Authorization info is required to request a transfer. */ - public static class MissingTransferRequestAuthInfoException extends AuthorizationErrorException { - public MissingTransferRequestAuthInfoException() { - super("Authorization info is required to request a transfer"); - } - } - - /** Registrar already sponsors the object of this transfer request. */ - public static class ObjectAlreadySponsoredException extends CommandUseErrorException { - public ObjectAlreadySponsoredException() { - super("Registrar already sponsors the object of this transfer request"); - } - } - - /** The resource is already pending transfer. */ - public static class AlreadyPendingTransferException extends ObjectPendingTransferException { - public AlreadyPendingTransferException(String targetId) { - super(targetId); - } - } -} diff --git a/java/google/registry/flows/domain/BaseDomainCheckFlow.java b/java/google/registry/flows/domain/BaseDomainCheckFlow.java deleted file mode 100644 index beff77f31..000000000 --- a/java/google/registry/flows/domain/BaseDomainCheckFlow.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows.domain; - -import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld; -import static google.registry.flows.domain.DomainFlowUtils.validateDomainName; -import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.net.InternetDomainName; -import google.registry.flows.EppException; -import google.registry.flows.ResourceCheckFlow; -import google.registry.model.domain.DomainCommand.Check; -import google.registry.model.domain.DomainResource; -import java.util.Map; - -/** An EPP flow that checks whether a domain can be provisioned. */ -public abstract class BaseDomainCheckFlow extends ResourceCheckFlow { - - protected Map domainNames; - - @Override - protected final void initCheckResourceFlow() throws EppException { - ImmutableMap.Builder domains = new ImmutableMap.Builder<>(); - ImmutableSet.Builder tlds = new ImmutableSet.Builder<>(); - for (String targetId : ImmutableSet.copyOf(targetIds)) { - // This validation is moderately expensive, so cache the results for getCheckData to use too. - InternetDomainName domainName = validateDomainName(targetId); - tlds.add(domainName.parent().toString()); - validateDomainNameWithIdnTables(domainName); - domains.put(targetId, domainName); - } - for (String tld : tlds.build()) { - checkAllowedAccessToTld(getAllowedTlds(), tld); - checkRegistryStateForTld(tld); - } - domainNames = domains.build(); - initDomainCheckFlow(); - } - - @SuppressWarnings("unused") - protected void initDomainCheckFlow() throws EppException {} -} diff --git a/java/google/registry/flows/domain/BaseDomainInfoFlow.java b/java/google/registry/flows/domain/BaseDomainInfoFlow.java deleted file mode 100644 index cc3dee09b..000000000 --- a/java/google/registry/flows/domain/BaseDomainInfoFlow.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Domain Registry 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.flows.domain; - -import static google.registry.util.CollectionUtils.forceEmptyToNull; - -import com.google.common.collect.ImmutableList; -import google.registry.flows.EppException; -import google.registry.flows.ResourceInfoFlow; -import google.registry.model.domain.DomainBase; -import google.registry.model.domain.DomainBase.Builder; -import google.registry.model.domain.DomainCommand; -import google.registry.model.domain.secdns.SecDnsInfoExtension; -import google.registry.model.eppoutput.EppResponse.ResponseExtension; - -/** - * An EPP flow that reads a domain resource or application. - * - * @param the resource type being manipulated - * @param a builder for the resource - */ -public abstract class BaseDomainInfoFlow> - extends ResourceInfoFlow { - @Override - protected final ImmutableList getResponseExtensions() throws EppException { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - // According to RFC 5910 section 2, we should only return this if the client specified the - // "urn:ietf:params:xml:ns:secDNS-1.1" when logging in. However, this is a "SHOULD" not a "MUST" - // and we are going to ignore it; clients who don't care about secDNS can just ignore it. - if (!existingResource.getDsData().isEmpty()) { - builder.add(SecDnsInfoExtension.create(existingResource.getDsData())); - } - return forceEmptyToNull(builder.addAll(getDomainResponseExtensions()).build()); - } - - /** Subclasses should override this to add their extensions. */ - protected abstract ImmutableList getDomainResponseExtensions() - throws EppException; -}