Fix bug which allowed creation of hosts with superordinate domains in pending delete state.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154716883
This commit is contained in:
mountford 2017-05-01 08:08:14 -07:00 committed by Ben McIlwain
parent 386d2bc6be
commit 11e7374c0f
7 changed files with 82 additions and 0 deletions

View file

@ -18,6 +18,7 @@ import static google.registry.flows.FlowUtils.validateClientIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.host.HostFlowUtils.lookupSuperordinateDomain;
import static google.registry.flows.host.HostFlowUtils.validateHostName;
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainNotInPendingDelete;
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership;
import static google.registry.model.EppResourceUtils.createRepoId;
import static google.registry.model.ofy.ObjectifyService.ofy;
@ -72,6 +73,7 @@ import org.joda.time.DateTime;
* @error {@link HostFlowUtils.HostNameNotNormalizedException}
* @error {@link HostFlowUtils.HostNameNotPunyCodedException}
* @error {@link HostFlowUtils.SuperordinateDomainDoesNotExistException}
* @error {@link HostFlowUtils.SuperordinateDomainInPendingDeleteException}
* @error {@link SubordinateHostMustHaveIpException}
* @error {@link UnexpectedExternalHostIpException}
*/
@ -101,6 +103,7 @@ public final class HostCreateFlow implements TransactionalFlow {
// we can detect error conditions earlier.
Optional<DomainResource> superordinateDomain =
lookupSuperordinateDomain(validateHostName(targetId), now);
verifySuperordinateDomainNotInPendingDelete(superordinateDomain.orNull());
verifySuperordinateDomainOwnership(clientId, superordinateDomain.orNull());
boolean willBeSubordinate = superordinateDomain.isPresent();
boolean hasIpAddresses = !isNullOrEmpty(command.getInetAddresses());

View file

@ -30,7 +30,9 @@ import google.registry.flows.EppException.ObjectDoesNotExistException;
import google.registry.flows.EppException.ParameterValuePolicyErrorException;
import google.registry.flows.EppException.ParameterValueRangeErrorException;
import google.registry.flows.EppException.ParameterValueSyntaxErrorException;
import google.registry.flows.EppException.StatusProhibitsOperationException;
import google.registry.model.domain.DomainResource;
import google.registry.model.eppcommon.StatusValue;
import google.registry.util.Idn;
import org.joda.time.DateTime;
@ -127,6 +129,24 @@ public class HostFlowUtils {
}
}
/** Ensure that the superordinate domain is not in pending delete. */
static void verifySuperordinateDomainNotInPendingDelete(
DomainResource superordinateDomain) throws EppException {
if ((superordinateDomain != null)
&& superordinateDomain.getStatusValues().contains(StatusValue.PENDING_DELETE)) {
throw new SuperordinateDomainInPendingDeleteException(
superordinateDomain.getFullyQualifiedDomainName());
}
}
/** Superordinate domain for this hostname is in pending delete. */
static class SuperordinateDomainInPendingDeleteException
extends StatusProhibitsOperationException {
public SuperordinateDomainInPendingDeleteException(String domainName) {
super(domainName);
}
}
/** Host names are limited to 253 characters. */
static class HostNameTooLongException extends ParameterValueRangeErrorException {
public HostNameTooLongException() {

View file

@ -24,6 +24,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.host.HostFlowUtils.lookupSuperordinateDomain;
import static google.registry.flows.host.HostFlowUtils.validateHostName;
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainNotInPendingDelete;
import static google.registry.flows.host.HostFlowUtils.verifySuperordinateDomainOwnership;
import static google.registry.model.index.ForeignKeyIndex.loadAndGetKey;
import static google.registry.model.ofy.ObjectifyService.ofy;
@ -90,6 +91,7 @@ import org.joda.time.DateTime;
* @error {@link HostFlowUtils.HostNameTooShallowException}
* @error {@link HostFlowUtils.InvalidHostNameException}
* @error {@link HostFlowUtils.SuperordinateDomainDoesNotExistException}
* @error {@link HostFlowUtils.SuperordinateDomainInPendingDeleteException}
* @error {@link CannotAddIpToExternalHostException}
* @error {@link CannotRemoveSubordinateHostLastIpException}
* @error {@link CannotRenameExternalHostException}
@ -139,6 +141,7 @@ public final class HostUpdateFlow implements TransactionalFlow {
// Note that lookupSuperordinateDomain calls cloneProjectedAtTime on the domain for us.
Optional<DomainResource> newSuperordinateDomain =
lookupSuperordinateDomain(validateHostName(newHostName), now);
verifySuperordinateDomainNotInPendingDelete(newSuperordinateDomain.orNull());
EppResource owningResource = firstNonNull(oldSuperordinateDomain, existingHost);
verifyUpdateAllowed(
command, existingHost, newSuperordinateDomain.orNull(), owningResource, isHostRename);

View file

@ -28,6 +28,7 @@ import com.googlecode.objectify.VoidWork;
import google.registry.config.RegistryConfig.Config;
import google.registry.mapreduce.MapreduceRunner;
import google.registry.model.domain.DomainResource;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.HostResource;
import google.registry.request.Action;
import google.registry.request.Parameter;
@ -107,6 +108,14 @@ public class RdeHostLinkAction implements Runnable {
logger.infofmt("Host %s is out of zone", xjcHost.getName());
return;
}
if (superordinateDomain.get().getStatusValues().contains(StatusValue.PENDING_DELETE)) {
getContext()
.incrementCounter(
"post-import hosts with superordinate domains in pending delete");
logger.infofmt(
"Host %s has a superordinate domain in pending delete", xjcHost.getName());
return;
}
// at this point, the host is definitely in zone and should be linked
getContext().incrementCounter("post-import hosts in zone");
final Key<DomainResource> superordinateDomainKey = Key.create(superordinateDomain.get());