Check PAK is present on billing domain flows (#1605)

* Check PAK on domain create

* Add unit test

* update docs

* Remove unneccesary setup

* Fix blank line

* Add check and test to all relevant flows

* Change error message
This commit is contained in:
sarahcaseybot
2022-04-29 14:30:24 -04:00
committed by GitHub
parent d0af81ecdf
commit 5d82893478
14 changed files with 184 additions and 0 deletions
@@ -20,6 +20,7 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest;
import static google.registry.flows.domain.DomainFlowUtils.isAnchorTenant;
@@ -100,6 +101,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.InvalidIdnDomainLabelException}
* @error {@link DomainFlowUtils.InvalidPunycodeException}
* @error {@link DomainFlowUtils.LeadingDashException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RestoresAreAlwaysForOneYearException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
@@ -153,6 +155,7 @@ public final class DomainCheckFlow implements Flow {
boolean tldFirstTimeSeen = seenTlds.add(tld);
if (tldFirstTimeSeen && !isSuperuser) {
checkAllowedAccessToTld(registrarId, tld);
checkHasBillingAccount(registrarId, tld);
verifyNotInPredelegation(Registry.get(tld), now);
}
}
@@ -17,6 +17,7 @@ package google.registry.flows.domain;
import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyTargetIdCount;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
@@ -60,6 +61,7 @@ import org.joda.time.DateTime;
* @error {@link google.registry.flows.FlowUtils.NotLoggedInException}
* @error {@link DomainFlowUtils.BadCommandForRegistryPhaseException}
* @error {@link DomainFlowUtils.ClaimsPeriodEndedException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
* @error {@link DomainClaimsCheckNotAllowedWithAllocationTokens}
@@ -99,6 +101,7 @@ public final class DomainClaimsCheckFlow implements Flow {
if (seenTlds.add(tld)) {
if (!isSuperuser) {
checkAllowedAccessToTld(registrarId, tld);
checkHasBillingAccount(registrarId, tld);
Registry registry = Registry.get(tld);
DateTime now = clock.nowUtc();
verifyNotInPredelegation(registry, now);
@@ -20,6 +20,7 @@ import static google.registry.flows.FlowUtils.validateRegistrarIsLoggedIn;
import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist;
import static google.registry.flows.domain.DomainFlowUtils.COLLISION_MESSAGE;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences;
import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse;
import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes;
@@ -180,6 +181,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.MalformedTcnIdException}
* @error {@link DomainFlowUtils.MaxSigLifeNotSupportedException}
* @error {@link DomainFlowUtils.MissingAdminContactException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.MissingClaimsNoticeException}
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingRegistrantException}
@@ -265,6 +267,7 @@ public final class DomainCreateFlow implements TransactionalFlow {
// registering premium domains.
if (!isSuperuser) {
checkAllowedAccessToTld(registrarId, registry.getTldStr());
checkHasBillingAccount(registrarId, registry.getTldStr());
boolean isValidReservedCreate = isValidReservedCreate(domainName, allocationToken);
verifyIsGaOrIsSpecialCase(tldState, isAnchorTenant, isValidReservedCreate, hasSignedMarks);
if (launchCreate.isPresent()) {
@@ -293,6 +293,17 @@ public class DomainFlowUtils {
}
}
/** Check if the registrar has the correct billing account map configured. */
public static void checkHasBillingAccount(String registrarId, String tld) throws EppException {
CurrencyUnit currency = Registry.get(tld).getCurrency();
if (!Registrar.loadByRegistrarIdCached(registrarId)
.get()
.getBillingAccountMap()
.containsKey(currency)) {
throw new DomainFlowUtils.MissingBillingAccountMapException(currency);
}
}
/** Check that the DS data that will be set on a domain is valid. */
static void validateDsData(Set<DelegationSignerData> dsData) throws EppException {
if (dsData != null) {
@@ -1501,6 +1512,13 @@ public class DomainFlowUtils {
}
}
/** Registrar is missing the billing account map for this currency type. */
public static class MissingBillingAccountMapException extends AuthorizationErrorException {
public MissingBillingAccountMapException(CurrencyUnit currency) {
super("Registrar is not fully onboarded for TLDs that bill in " + currency);
}
}
/** Registrant is not allow-listed for this TLD. */
public static class RegistrantNotAllowedException extends StatusProhibitsOperationException {
public RegistrantNotAllowedException(String contactId) {
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEvent;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
@@ -106,6 +107,7 @@ import org.joda.time.Duration;
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
@@ -263,6 +265,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
if (!isSuperuser) {
verifyResourceOwnership(registrarId, existingDomain);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
checkHasBillingAccount(registrarId, existingDomain.getTld());
}
verifyUnitIsYears(command.getPeriod());
// If the date they specify doesn't match the expiration, fail. (This is an idempotence check).
@@ -20,6 +20,7 @@ import static google.registry.flows.ResourceFlowUtils.loadAndVerifyExistence;
import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyResourceOwnership;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEvent;
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
@@ -104,6 +105,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.DomainReservedException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
@@ -216,6 +218,7 @@ public final class DomainRestoreRequestFlow implements TransactionalFlow {
verifyNotReserved(InternetDomainName.from(targetId), false);
verifyPremiumNameIsNotBlocked(targetId, now, registrarId);
checkAllowedAccessToTld(registrarId, existingDomain.getTld());
checkHasBillingAccount(registrarId, existingDomain.getTld());
}
// No other changes can be specified on a restore request.
if (!command.noChangesPresent()) {
@@ -22,6 +22,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyAuthInfo;
import static google.registry.flows.ResourceFlowUtils.verifyAuthInfoPresentForResourceTransfer;
import static google.registry.flows.ResourceFlowUtils.verifyNoDisallowedStatuses;
import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld;
import static google.registry.flows.domain.DomainFlowUtils.checkHasBillingAccount;
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
import static google.registry.flows.domain.DomainFlowUtils.verifyPremiumNameIsNotBlocked;
@@ -111,6 +112,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.CurrencyValueScaleException}
* @error {@link DomainFlowUtils.FeesMismatchException}
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
* @error {@link DomainFlowUtils.MissingBillingAccountMapException}
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrarMustBeActiveForThisOperationException}
@@ -273,6 +275,7 @@ public final class DomainTransferRequestFlow implements TransactionalFlow {
verifyTransferPeriod(period, superuserExtension);
if (!isSuperuser) {
checkAllowedAccessToTld(gainingClientId, existingDomain.getTld());
checkHasBillingAccount(gainingClientId, existingDomain.getTld());
verifyPremiumNameIsNotBlocked(targetId, now, gainingClientId);
}
}