Deny non-active registrars access to non-free EPP commands

Registrars that are PENDING or SUSPENDED should not have access to
EPP commands that cost money, as in either case it's not likely we'd
actually be able to get payment from said registrar. For this reason
we already prevented access to the domain create flow for non-active
registrars. This commit extends that to other commands that cost
money, including renewals, restores, and transfer requests.

Note that implicit autorenews will still occur for suspended
registrars, as in our point-in-time data model there's no good way
to prevent them. So when a registrar is suspended for non-payment,
the game plan is to get all of their domains transferred out to a
registrar that will pay as soon as possible.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=223173677
This commit is contained in:
mcilwain 2018-11-28 08:41:05 -08:00 committed by jianglai
parent dbdc69916a
commit 11da64bee2
13 changed files with 172 additions and 15 deletions

View file

@ -98,6 +98,8 @@ import org.joda.time.Duration;
/**
* An EPP flow that allocates a new domain resource from a domain application.
*
* <p>Note that this flow is only run by superusers.
*
* @error {@link google.registry.flows.exceptions.ResourceAlreadyExistsException}
* @error {@link DomainAllocateFlow.HasFinalStatusException}
* @error {@link DomainAllocateFlow.MissingApplicationException}

View file

@ -147,7 +147,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveToCreateDomainsException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowTmchUtils.SignedMarksMustBeEncodedException}
* @error {@link DomainFlowTmchUtils.SignedMarkCertificateExpiredException}
* @error {@link DomainFlowTmchUtils.SignedMarkCertificateInvalidException}

View file

@ -179,7 +179,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverWhitelistException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveToCreateDomainsException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
* @error {@link DomainFlowUtils.TooManyDsRecordsException}
* @error {@link DomainFlowUtils.TooManyNameserversException}

View file

@ -892,13 +892,14 @@ public class DomainFlowUtils {
/**
* Check that the registrar with the given client ID is active.
*
* <p>Non-active registrars are not allowed to create domain applications or domain resources.
* <p>Non-active registrars are not allowed to run operations that cost money, like domain creates
* or renews.
*/
static void verifyRegistrarIsActive(String clientId)
throws RegistrarMustBeActiveToCreateDomainsException {
throws RegistrarMustBeActiveForThisOperationException {
Registrar registrar = Registrar.loadByClientIdCached(clientId).get();
if (registrar.getState() != State.ACTIVE) {
throw new RegistrarMustBeActiveToCreateDomainsException();
throw new RegistrarMustBeActiveForThisOperationException();
}
}
@ -1606,10 +1607,10 @@ public class DomainFlowUtils {
}
}
/** Registrar must be active in order to create domains or applications. */
static class RegistrarMustBeActiveToCreateDomainsException extends AuthorizationErrorException {
public RegistrarMustBeActiveToCreateDomainsException() {
super("Registrar must be active in order to create domains or applications");
/** Registrar must be active in order to perform this operation. */
static class RegistrarMustBeActiveForThisOperationException extends AuthorizationErrorException {
public RegistrarMustBeActiveForThisOperationException() {
super("Registrar must be active in order to perform this operation");
}
}
}

View file

@ -26,6 +26,7 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessa
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive;
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
@ -101,6 +102,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
* @error {@link DomainRenewFlow.IncorrectCurrentExpirationDateException}
*/
@ -133,6 +135,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
flowCustomLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);
verifyRegistrarIsActive(clientId);
DateTime now = ofy().getTransactionTime();
Renew command = (Renew) resourceCommand;
// Loads the target resource if it exists

View file

@ -25,6 +25,7 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessa
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
import static google.registry.flows.domain.DomainFlowUtils.verifyNotReserved;
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
@ -101,6 +102,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
* @error {@link DomainRestoreRequestFlow.DomainNotEligibleForRestoreException}
* @error {@link DomainRestoreRequestFlow.RestoreCommandIncludesChangesException}
@ -129,6 +131,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
RgpUpdateExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(clientId);
verifyRegistrarIsActive(clientId);
Update command = (Update) resourceCommand;
DateTime now = ofy().getTransactionTime();
DomainResource existingDomain = loadAndVerifyExistence(DomainResource.class, targetId, now);

View file

@ -23,6 +23,7 @@ import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToT
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
import static google.registry.flows.domain.DomainFlowUtils.verifyRegistrarIsActive;
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
import static google.registry.flows.domain.DomainTransferUtils.createLosingTransferPollMessage;
import static google.registry.flows.domain.DomainTransferUtils.createPendingTransferData;
@ -107,6 +108,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
*/
@ReportingSpec(ActivityReportField.DOMAIN_TRANSFER_REQUEST)
@ -139,6 +141,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
MetadataExtension.class);
extensionManager.validate();
validateClientIsLoggedIn(gainingClientId);
verifyRegistrarIsActive(gainingClientId);
DateTime now = ofy().getTransactionTime();
DomainResource existingDomain = loadAndVerifyExistence(DomainResource.class, targetId, now);
Optional<DomainTransferRequestSuperuserExtension> superuserExtension =