Delete some of the old hierarchical flow files

These have already been totally replaced by flattened flows.
There are a few left that will get deleted when the remaining
flat flows go in.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=134077510
This commit is contained in:
cgoldfeder 2016-09-23 08:38:19 -07:00 committed by Ben McIlwain
parent add9474e9a
commit dbb3977bcf
15 changed files with 0 additions and 1125 deletions

View file

@ -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 <R> the resource type being manipulated
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class OwnedResourceMutatePendingTransferFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends ResourceMutatePendingTransferFlow<R, B, C> {
/** 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 {}
}

View file

@ -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 <R> the resource type being changed
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceAsyncDeleteFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends ResourceDeleteFlow<R, C> {
@Override
public void failfast() throws ResourceToDeleteIsReferencedException {
// Enter a transactionless context briefly.
boolean isLinked = ofy().doTransactionless(new Work<Boolean>() {
@Override
public Boolean run() {
ForeignKeyIndex<R> 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<R> 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");
}
}
}

View file

@ -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 <R> the resource type being manipulated
* @param <C> the overall command type doing the manipulation.
*/
public abstract class ResourceCheckFlow<R extends EppResource, C extends ResourceCheck>
extends ResourceFlow<R, C> {
protected List<String> 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<? extends ResponseExtension> 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()));
}
}
}

View file

@ -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 <R> the resource type being changed
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceDeleteFlow<R extends EppResource, C extends SingleResourceCommand>
extends OwnedResourceMutateFlow<R, C> {
private static final Set<StatusValue> 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<StatusValue> 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<? extends ResponseExtension> getDeleteResponseExtensions() {
return null;
}
}

View file

@ -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 <R> the resource type being manipulated
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceInfoFlow<R extends EppResource, C extends SingleResourceCommand>
extends ResourceQueryFlow<R, C> {
@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<? extends ResponseExtension> getResponseExtensions() throws EppException {
return null;
}
}

View file

@ -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 <R> the resource type being changed
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceMutatePendingTransferFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends ResourceTransferFlow<R, C> {
/** 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);
}
}
}

View file

@ -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 <R> the resource type being changed
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceSyncDeleteFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends ResourceDeleteFlow<R, C> {
@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() {}
}

View file

@ -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 <R> the resource type being manipulated
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferApproveFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends OwnedResourceMutatePendingTransferFlow<R, B, C> {
@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() {}
}

View file

@ -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 <R> the resource type being manipulated
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferCancelFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends ResourceMutatePendingTransferFlow<R, B, C> {
/** 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");
}
}
}

View file

@ -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 <R> the resource type being manipulated
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferFlow
<R extends EppResource, C extends SingleResourceCommand> extends ResourceMutateFlow<R, C> {}

View file

@ -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 <R> the resource type being manipulated
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferQueryFlow<R extends EppResource,
C extends SingleResourceCommand> extends ResourceQueryFlow<R, C> {
@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");
}
}
}

View file

@ -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 <R> the resource type being manipulated
* @param <B> a builder for the resource
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferRejectFlow
<R extends EppResource, B extends Builder<R, ?>, C extends SingleResourceCommand>
extends OwnedResourceMutatePendingTransferFlow<R, B, C> {
@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() {}
}

View file

@ -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 <R> the resource type being manipulated
* @param <C> the command type, marshalled directly from the epp xml
*/
public abstract class ResourceTransferRequestFlow
<R extends EppResource, C extends SingleResourceCommand> extends ResourceTransferFlow<R, C> {
private static final Set<StatusValue> 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> 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<Key<? extends TransferServerApproveEntity>> 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<? extends ResponseExtension> getTransferResponseExtensions() {
return null;
}
@Override
protected final Set<StatusValue> 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);
}
}
}

View file

@ -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<DomainResource, Check> {
protected Map<String, InternetDomainName> domainNames;
@Override
protected final void initCheckResourceFlow() throws EppException {
ImmutableMap.Builder<String, InternetDomainName> domains = new ImmutableMap.Builder<>();
ImmutableSet.Builder<String> 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 {}
}

View file

@ -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 <R> the resource type being manipulated
* @param <B> a builder for the resource
*/
public abstract class BaseDomainInfoFlow<R extends DomainBase, B extends Builder<R, B>>
extends ResourceInfoFlow<R, DomainCommand.Info> {
@Override
protected final ImmutableList<ResponseExtension> getResponseExtensions() throws EppException {
ImmutableList.Builder<ResponseExtension> 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<? extends ResponseExtension> getDomainResponseExtensions()
throws EppException;
}