mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 07:57:13 +02:00
Add period restriction to domain flows
Specifically, Domain[Create,Allocate,ApplicationCreate]Flow ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=147458283
This commit is contained in:
parent
335b3f0cf8
commit
53262d82bb
14 changed files with 171 additions and 21 deletions
|
@ -529,9 +529,9 @@ comes in at the exact millisecond that the domain would have expired.
|
||||||
* Fees must be explicitly acknowledged when performing any operations on a
|
* Fees must be explicitly acknowledged when performing any operations on a
|
||||||
premium name.
|
premium name.
|
||||||
* 2004
|
* 2004
|
||||||
|
* New registration period exceeds maximum number of years.
|
||||||
* The fees passed in the transform command do not match the fees that will
|
* The fees passed in the transform command do not match the fees that will
|
||||||
be charged.
|
be charged.
|
||||||
* New registration period exceeds maximum number of years.
|
|
||||||
* The current expiration date is incorrect.
|
* The current expiration date is incorrect.
|
||||||
* 2005
|
* 2005
|
||||||
* The requested fee is expressed in a scale that is invalid for the given
|
* The requested fee is expressed in a scale that is invalid for the given
|
||||||
|
@ -620,6 +620,7 @@ An EPP flow that creates a new domain resource.
|
||||||
* 2004
|
* 2004
|
||||||
* The acceptance time specified in the claim notice is more than 48 hours
|
* The acceptance time specified in the claim notice is more than 48 hours
|
||||||
in the past.
|
in the past.
|
||||||
|
* New registration period exceeds maximum number of years.
|
||||||
* The expiration time specified in the claim notice has elapsed.
|
* The expiration time specified in the claim notice has elapsed.
|
||||||
* The fees passed in the transform command do not match the fees that will
|
* The fees passed in the transform command do not match the fees that will
|
||||||
be charged.
|
be charged.
|
||||||
|
@ -830,6 +831,7 @@ An EPP flow that creates a new application for a domain resource.
|
||||||
* 2004
|
* 2004
|
||||||
* The acceptance time specified in the claim notice is more than 48 hours
|
* The acceptance time specified in the claim notice is more than 48 hours
|
||||||
in the past.
|
in the past.
|
||||||
|
* New registration period exceeds maximum number of years.
|
||||||
* The expiration time specified in the claim notice has elapsed.
|
* The expiration time specified in the claim notice has elapsed.
|
||||||
* The fees passed in the transform command do not match the fees that will
|
* The fees passed in the transform command do not match the fees that will
|
||||||
be charged.
|
be charged.
|
||||||
|
@ -907,6 +909,8 @@ An EPP flow that allocates a new domain resource from a domain application.
|
||||||
|
|
||||||
### Errors
|
### Errors
|
||||||
|
|
||||||
|
* 2004
|
||||||
|
* New registration period exceeds maximum number of years.
|
||||||
* 2201
|
* 2201
|
||||||
* Only a superuser can allocate domains.
|
* Only a superuser can allocate domains.
|
||||||
* 2302
|
* 2302
|
||||||
|
|
|
@ -26,6 +26,7 @@ import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpToken
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers;
|
import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
||||||
|
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||||
import static google.registry.model.EppResourceUtils.createDomainRepoId;
|
import static google.registry.model.EppResourceUtils.createDomainRepoId;
|
||||||
|
@ -94,6 +95,7 @@ import org.joda.time.DateTime;
|
||||||
* @error {@link DomainAllocateFlow.HasFinalStatusException}
|
* @error {@link DomainAllocateFlow.HasFinalStatusException}
|
||||||
* @error {@link DomainAllocateFlow.MissingApplicationException}
|
* @error {@link DomainAllocateFlow.MissingApplicationException}
|
||||||
* @error {@link DomainAllocateFlow.OnlySuperuserCanAllocateException}
|
* @error {@link DomainAllocateFlow.OnlySuperuserCanAllocateException}
|
||||||
|
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
|
||||||
*/
|
*/
|
||||||
public class DomainAllocateFlow implements TransactionalFlow {
|
public class DomainAllocateFlow implements TransactionalFlow {
|
||||||
|
|
||||||
|
@ -134,6 +136,7 @@ public class DomainAllocateFlow implements TransactionalFlow {
|
||||||
Period period = command.getPeriod();
|
Period period = command.getPeriod();
|
||||||
Integer years = period.getValue();
|
Integer years = period.getValue();
|
||||||
verifyUnitIsYears(period);
|
verifyUnitIsYears(period);
|
||||||
|
validateRegistrationPeriod(years);
|
||||||
validateCreateCommandContactsAndNameservers(command, registry.getTldStr());
|
validateCreateCommandContactsAndNameservers(command, registry.getTldStr());
|
||||||
SecDnsCreateExtension secDnsCreate =
|
SecDnsCreateExtension secDnsCreate =
|
||||||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateLaunchCreateNotice;
|
import static google.registry.flows.domain.DomainFlowUtils.validateLaunchCreateNotice;
|
||||||
|
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsNoticeIfAndOnlyIfNeeded;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsNoticeIfAndOnlyIfNeeded;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
|
||||||
|
@ -117,6 +118,7 @@ import org.joda.time.DateTime;
|
||||||
* @error {@link DomainFlowUtils.DomainReservedException}
|
* @error {@link DomainFlowUtils.DomainReservedException}
|
||||||
* @error {@link DomainFlowUtils.DuplicateContactForRoleException}
|
* @error {@link DomainFlowUtils.DuplicateContactForRoleException}
|
||||||
* @error {@link DomainFlowUtils.EmptyDomainNamePartException}
|
* @error {@link DomainFlowUtils.EmptyDomainNamePartException}
|
||||||
|
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
|
||||||
* @error {@link DomainFlowUtils.ExpiredClaimException}
|
* @error {@link DomainFlowUtils.ExpiredClaimException}
|
||||||
* @error {@link DomainFlowUtils.FeesMismatchException}
|
* @error {@link DomainFlowUtils.FeesMismatchException}
|
||||||
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
||||||
|
@ -203,6 +205,7 @@ public final class DomainApplicationCreateFlow implements TransactionalFlow {
|
||||||
// notice without specifying a claims key, and override blocks on registering premium domains.
|
// notice without specifying a claims key, and override blocks on registering premium domains.
|
||||||
verifyUnitIsYears(command.getPeriod());
|
verifyUnitIsYears(command.getPeriod());
|
||||||
int years = command.getPeriod().getValue();
|
int years = command.getPeriod().getValue();
|
||||||
|
validateRegistrationPeriod(years);
|
||||||
validateCreateCommandContactsAndNameservers(command, tld);
|
validateCreateCommandContactsAndNameservers(command, tld);
|
||||||
LaunchCreateExtension launchCreate = eppInput.getSingleExtension(LaunchCreateExtension.class);
|
LaunchCreateExtension launchCreate = eppInput.getSingleExtension(LaunchCreateExtension.class);
|
||||||
if (launchCreate != null) {
|
if (launchCreate != null) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import static google.registry.flows.domain.DomainFlowUtils.validateDomainName;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
import static google.registry.flows.domain.DomainFlowUtils.validateDomainNameWithIdnTables;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateLaunchCreateNotice;
|
import static google.registry.flows.domain.DomainFlowUtils.validateLaunchCreateNotice;
|
||||||
|
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
import static google.registry.flows.domain.DomainFlowUtils.validateSecDnsExtension;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsNoticeIfAndOnlyIfNeeded;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsNoticeIfAndOnlyIfNeeded;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyClaimsPeriodNotEnded;
|
||||||
|
@ -116,6 +117,7 @@ import org.joda.time.DateTime;
|
||||||
* @error {@link DomainFlowUtils.DomainReservedException}
|
* @error {@link DomainFlowUtils.DomainReservedException}
|
||||||
* @error {@link DomainFlowUtils.DuplicateContactForRoleException}
|
* @error {@link DomainFlowUtils.DuplicateContactForRoleException}
|
||||||
* @error {@link DomainFlowUtils.EmptyDomainNamePartException}
|
* @error {@link DomainFlowUtils.EmptyDomainNamePartException}
|
||||||
|
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
|
||||||
* @error {@link DomainFlowUtils.ExpiredClaimException}
|
* @error {@link DomainFlowUtils.ExpiredClaimException}
|
||||||
* @error {@link DomainFlowUtils.FeesMismatchException}
|
* @error {@link DomainFlowUtils.FeesMismatchException}
|
||||||
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
||||||
|
@ -242,6 +244,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
validateSecDnsExtension(eppInput.getSingleExtension(SecDnsCreateExtension.class));
|
||||||
String repoId = createDomainRepoId(ObjectifyService.allocateId(), registry.getTldStr());
|
String repoId = createDomainRepoId(ObjectifyService.allocateId(), registry.getTldStr());
|
||||||
DateTime registrationExpirationTime = leapSafeAddYears(now, years);
|
DateTime registrationExpirationTime = leapSafeAddYears(now, years);
|
||||||
|
validateRegistrationPeriod(years);
|
||||||
HistoryEntry historyEntry = buildHistory(repoId, period, now);
|
HistoryEntry historyEntry = buildHistory(repoId, period, now);
|
||||||
// Bill for the create.
|
// Bill for the create.
|
||||||
BillingEvent.OneTime createBillingEvent =
|
BillingEvent.OneTime createBillingEvent =
|
||||||
|
|
|
@ -22,6 +22,8 @@ import static com.google.common.collect.Sets.difference;
|
||||||
import static com.google.common.collect.Sets.union;
|
import static com.google.common.collect.Sets.union;
|
||||||
import static google.registry.flows.domain.DomainPricingLogic.getMatchingLrpToken;
|
import static google.registry.flows.domain.DomainPricingLogic.getMatchingLrpToken;
|
||||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||||
|
import static google.registry.model.domain.DomainResource.MAX_REGISTRATION_YEARS;
|
||||||
|
import static google.registry.model.domain.DomainResource.extendRegistrationWithCap;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.model.registry.Registries.findTldForName;
|
import static google.registry.model.registry.Registries.findTldForName;
|
||||||
import static google.registry.model.registry.label.ReservedList.getReservation;
|
import static google.registry.model.registry.label.ReservedList.getReservation;
|
||||||
|
@ -30,6 +32,7 @@ import static google.registry.tldconfig.idn.IdnLabelValidator.findValidIdnTableF
|
||||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||||
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
import static google.registry.util.DateTimeUtils.END_OF_TIME;
|
||||||
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
import static google.registry.util.DateTimeUtils.isAtOrAfter;
|
||||||
|
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||||
import static google.registry.util.DomainNameUtils.ACE_PREFIX;
|
import static google.registry.util.DomainNameUtils.ACE_PREFIX;
|
||||||
|
|
||||||
import com.google.common.base.CharMatcher;
|
import com.google.common.base.CharMatcher;
|
||||||
|
@ -262,7 +265,6 @@ public class DomainFlowUtils {
|
||||||
|
|
||||||
private static void verifyNotInPendingDelete(
|
private static void verifyNotInPendingDelete(
|
||||||
Key<? extends EppResource> resourceKey) throws EppException {
|
Key<? extends EppResource> resourceKey) throws EppException {
|
||||||
|
|
||||||
EppResource resource = ofy().load().key(resourceKey).now();
|
EppResource resource = ofy().load().key(resourceKey).now();
|
||||||
if (resource.getStatusValues().contains(StatusValue.PENDING_DELETE)) {
|
if (resource.getStatusValues().contains(StatusValue.PENDING_DELETE)) {
|
||||||
throw new LinkedResourceInPendingDeleteProhibitsOperationException(resource.getForeignKey());
|
throw new LinkedResourceInPendingDeleteProhibitsOperationException(resource.getForeignKey());
|
||||||
|
@ -621,6 +623,35 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a new registration period (via a renew) does not extend beyond a maximum number
|
||||||
|
* of years (e.g. {@link DomainResource#MAX_REGISTRATION_YEARS}).
|
||||||
|
*
|
||||||
|
* @throws ExceedsMaxRegistrationYearsException if the new registration period is too long
|
||||||
|
*/
|
||||||
|
public static void validateRegistrationPeriod(
|
||||||
|
DateTime now,
|
||||||
|
DateTime oldExpirationTime,
|
||||||
|
int years) throws EppException {
|
||||||
|
DateTime newExpirationTime = leapSafeAddYears(oldExpirationTime, years); // uncapped
|
||||||
|
if (extendRegistrationWithCap(now, oldExpirationTime, years).isBefore(newExpirationTime)) {
|
||||||
|
throw new ExceedsMaxRegistrationYearsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a new registration period (via a create, allocate, or application create) does
|
||||||
|
* not extend beyond a maximum number of years (e.g.
|
||||||
|
* {@link DomainResource#MAX_REGISTRATION_YEARS}).
|
||||||
|
*
|
||||||
|
* @throws ExceedsMaxRegistrationYearsException if the new registration period is too long
|
||||||
|
*/
|
||||||
|
public static void validateRegistrationPeriod(int years) throws EppException {
|
||||||
|
if (years > MAX_REGISTRATION_YEARS) {
|
||||||
|
throw new ExceedsMaxRegistrationYearsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a secDns extension to a list if the given set of dsData is non-empty.
|
* Adds a secDns extension to a list if the given set of dsData is non-empty.
|
||||||
*
|
*
|
||||||
|
@ -830,7 +861,7 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a response extension listign the fees on a domain or application create. */
|
/** Create a response extension listing the fees on a domain or application create. */
|
||||||
static FeeTransformResponseExtension createFeeCreateResponse(
|
static FeeTransformResponseExtension createFeeCreateResponse(
|
||||||
FeeTransformCommandExtension feeCreate, FeesAndCredits feesAndCredits) {
|
FeeTransformCommandExtension feeCreate, FeesAndCredits feesAndCredits) {
|
||||||
return feeCreate
|
return feeCreate
|
||||||
|
@ -1260,4 +1291,13 @@ public class DomainFlowUtils {
|
||||||
super("Only encoded signed marks are supported");
|
super("Only encoded signed marks are supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** New registration period exceeds maximum number of years. */
|
||||||
|
static class ExceedsMaxRegistrationYearsException extends ParameterValueRangeErrorException {
|
||||||
|
public ExceedsMaxRegistrationYearsException() {
|
||||||
|
super(String.format(
|
||||||
|
"New registration period exceeds maximum number of years (%d)",
|
||||||
|
MAX_REGISTRATION_YEARS));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,8 @@ import static google.registry.flows.domain.DomainFlowUtils.newAutorenewBillingEv
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
|
import static google.registry.flows.domain.DomainFlowUtils.newAutorenewPollMessage;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
|
import static google.registry.flows.domain.DomainFlowUtils.updateAutorenewRecurrenceEndTime;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
import static google.registry.flows.domain.DomainFlowUtils.validateFeeChallenge;
|
||||||
|
import static google.registry.flows.domain.DomainFlowUtils.validateRegistrationPeriod;
|
||||||
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
import static google.registry.flows.domain.DomainFlowUtils.verifyUnitIsYears;
|
||||||
import static google.registry.model.domain.DomainResource.MAX_REGISTRATION_YEARS;
|
|
||||||
import static google.registry.model.domain.DomainResource.extendRegistrationWithCap;
|
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
import static google.registry.util.DateTimeUtils.leapSafeAddYears;
|
||||||
|
|
||||||
|
@ -95,12 +94,12 @@ import org.joda.time.DateTime;
|
||||||
* @error {@link DomainFlowUtils.BadPeriodUnitException}
|
* @error {@link DomainFlowUtils.BadPeriodUnitException}
|
||||||
* @error {@link DomainFlowUtils.CurrencyUnitMismatchException}
|
* @error {@link DomainFlowUtils.CurrencyUnitMismatchException}
|
||||||
* @error {@link DomainFlowUtils.CurrencyValueScaleException}
|
* @error {@link DomainFlowUtils.CurrencyValueScaleException}
|
||||||
|
* @error {@link DomainFlowUtils.ExceedsMaxRegistrationYearsException}
|
||||||
* @error {@link DomainFlowUtils.FeesMismatchException}
|
* @error {@link DomainFlowUtils.FeesMismatchException}
|
||||||
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
* @error {@link DomainFlowUtils.FeesRequiredForPremiumNameException}
|
||||||
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
|
* @error {@link DomainFlowUtils.NotAuthorizedForTldException}
|
||||||
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
|
* @error {@link DomainFlowUtils.UnsupportedFeeAttributeException}
|
||||||
* @error {@link DomainRenewFlow.DomainHasPendingTransferException}
|
* @error {@link DomainRenewFlow.DomainHasPendingTransferException}
|
||||||
* @error {@link DomainRenewFlow.ExceedsMaxRegistrationYearsException}
|
|
||||||
* @error {@link DomainRenewFlow.IncorrectCurrentExpirationDateException}
|
* @error {@link DomainRenewFlow.IncorrectCurrentExpirationDateException}
|
||||||
*/
|
*/
|
||||||
public final class DomainRenewFlow implements TransactionalFlow {
|
public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
|
@ -154,9 +153,7 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
.build();
|
.build();
|
||||||
DateTime oldExpirationTime = existingDomain.getRegistrationExpirationTime();
|
DateTime oldExpirationTime = existingDomain.getRegistrationExpirationTime();
|
||||||
DateTime newExpirationTime = leapSafeAddYears(oldExpirationTime, years); // Uncapped
|
DateTime newExpirationTime = leapSafeAddYears(oldExpirationTime, years); // Uncapped
|
||||||
if (extendRegistrationWithCap(now, oldExpirationTime, years).isBefore(newExpirationTime)) {
|
validateRegistrationPeriod(now, oldExpirationTime, years);
|
||||||
throw new ExceedsMaxRegistrationYearsException();
|
|
||||||
}
|
|
||||||
String tld = existingDomain.getTld();
|
String tld = existingDomain.getTld();
|
||||||
// Bill for this explicit renew itself.
|
// Bill for this explicit renew itself.
|
||||||
BillingEvent.OneTime explicitRenewEvent =
|
BillingEvent.OneTime explicitRenewEvent =
|
||||||
|
@ -271,13 +268,4 @@ public final class DomainRenewFlow implements TransactionalFlow {
|
||||||
super("The current expiration date is incorrect");
|
super("The current expiration date is incorrect");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** New registration period exceeds maximum number of years. */
|
|
||||||
static class ExceedsMaxRegistrationYearsException extends ParameterValueRangeErrorException {
|
|
||||||
public ExceedsMaxRegistrationYearsException() {
|
|
||||||
super(String.format(
|
|
||||||
"Registrations cannot extend for more than %d years into the future",
|
|
||||||
MAX_REGISTRATION_YEARS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import google.registry.model.transfer.TransferData;
|
||||||
import google.registry.model.transfer.TransferStatus;
|
import google.registry.model.transfer.TransferStatus;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.Interval;
|
import org.joda.time.Interval;
|
||||||
|
|
||||||
|
@ -334,11 +335,14 @@ public class DomainResource extends DomainBase
|
||||||
|
|
||||||
/** Return what the expiration time would be if the given number of years were added to it. */
|
/** Return what the expiration time would be if the given number of years were added to it. */
|
||||||
public static DateTime extendRegistrationWithCap(
|
public static DateTime extendRegistrationWithCap(
|
||||||
DateTime now, DateTime currentExpirationTime, Integer extendedRegistrationYears) {
|
DateTime now,
|
||||||
|
DateTime currentExpirationTime,
|
||||||
|
@Nullable Integer extendedRegistrationYears) {
|
||||||
// We must cap registration at the max years (aka 10), even if that truncates the last year.
|
// We must cap registration at the max years (aka 10), even if that truncates the last year.
|
||||||
return earliestOf(
|
return earliestOf(
|
||||||
leapSafeAddYears(
|
leapSafeAddYears(
|
||||||
currentExpirationTime, Optional.fromNullable(extendedRegistrationYears).or(0)),
|
currentExpirationTime,
|
||||||
|
Optional.fromNullable(extendedRegistrationYears).or(0)),
|
||||||
leapSafeAddYears(now, MAX_REGISTRATION_YEARS));
|
leapSafeAddYears(now, MAX_REGISTRATION_YEARS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import google.registry.flows.ResourceFlowTestCase;
|
||||||
import google.registry.flows.domain.DomainAllocateFlow.HasFinalStatusException;
|
import google.registry.flows.domain.DomainAllocateFlow.HasFinalStatusException;
|
||||||
import google.registry.flows.domain.DomainAllocateFlow.MissingApplicationException;
|
import google.registry.flows.domain.DomainAllocateFlow.MissingApplicationException;
|
||||||
import google.registry.flows.domain.DomainAllocateFlow.OnlySuperuserCanAllocateException;
|
import google.registry.flows.domain.DomainAllocateFlow.OnlySuperuserCanAllocateException;
|
||||||
|
import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsException;
|
||||||
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
import google.registry.model.billing.BillingEvent.Flag;
|
import google.registry.model.billing.BillingEvent.Flag;
|
||||||
|
@ -484,4 +485,12 @@ public class DomainAllocateFlowTest
|
||||||
thrown.expect(OnlySuperuserCanAllocateException.class);
|
thrown.expect(OnlySuperuserCanAllocateException.class);
|
||||||
runFlow(CommitMode.LIVE, UserPrivileges.NORMAL);
|
runFlow(CommitMode.LIVE, UserPrivileges.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_max10Years() throws Exception {
|
||||||
|
setupDomainApplication("tld", TldState.QUIET_PERIOD);
|
||||||
|
setEppInput("domain_allocate_11_years.xml");
|
||||||
|
thrown.expect(ExceedsMaxRegistrationYearsException.class);
|
||||||
|
runFlowAsSuperuser();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ import google.registry.flows.domain.DomainFlowUtils.DomainLabelTooLongException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.DomainReservedException;
|
import google.registry.flows.domain.DomainFlowUtils.DomainReservedException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.DuplicateContactForRoleException;
|
import google.registry.flows.domain.DomainFlowUtils.DuplicateContactForRoleException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.EmptyDomainNamePartException;
|
import google.registry.flows.domain.DomainFlowUtils.EmptyDomainNamePartException;
|
||||||
|
import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.ExpiredClaimException;
|
import google.registry.flows.domain.DomainFlowUtils.ExpiredClaimException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
||||||
|
@ -1575,6 +1576,16 @@ public class DomainApplicationCreateFlowTest
|
||||||
runFlow();
|
runFlow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_max10Years() throws Exception {
|
||||||
|
createTld("tld", TldState.LANDRUSH);
|
||||||
|
setEppInput("domain_create_landrush_11_years.xml");
|
||||||
|
persistContactsAndHosts();
|
||||||
|
clock.advanceOneMilli();
|
||||||
|
thrown.expect(ExceedsMaxRegistrationYearsException.class);
|
||||||
|
runFlow();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There is special logic that disallows a failfast for domains in add grace period and sunrush
|
* There is special logic that disallows a failfast for domains in add grace period and sunrush
|
||||||
* add grace period, so make sure that they fail anyways in the actual flow.
|
* add grace period, so make sure that they fail anyways in the actual flow.
|
||||||
|
|
|
@ -70,6 +70,7 @@ import google.registry.flows.domain.DomainFlowUtils.DomainLabelTooLongException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.DomainReservedException;
|
import google.registry.flows.domain.DomainFlowUtils.DomainReservedException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.DuplicateContactForRoleException;
|
import google.registry.flows.domain.DomainFlowUtils.DuplicateContactForRoleException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.EmptyDomainNamePartException;
|
import google.registry.flows.domain.DomainFlowUtils.EmptyDomainNamePartException;
|
||||||
|
import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.ExpiredClaimException;
|
import google.registry.flows.domain.DomainFlowUtils.ExpiredClaimException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
||||||
|
@ -1792,4 +1793,12 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
.build());
|
.build());
|
||||||
doSuccessfulTest("tld", "domain_create_response.xml");
|
doSuccessfulTest("tld", "domain_create_response.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailure_max10Years() throws Exception {
|
||||||
|
setEppInput("domain_create_11_years.xml");
|
||||||
|
persistContactsAndHosts();
|
||||||
|
thrown.expect(ExceedsMaxRegistrationYearsException.class);
|
||||||
|
runFlow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package google.registry.flows.domain;
|
package google.registry.flows.domain;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.domain.DomainTransferFlowTestCase.persistWithPendingTransfer;
|
import static google.registry.flows.domain.DomainTransferFlowTestCase.persistWithPendingTransfer;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
|
@ -40,12 +41,12 @@ import google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.BadPeriodUnitException;
|
import google.registry.flows.domain.DomainFlowUtils.BadPeriodUnitException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException;
|
import google.registry.flows.domain.DomainFlowUtils.CurrencyUnitMismatchException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
|
import google.registry.flows.domain.DomainFlowUtils.CurrencyValueScaleException;
|
||||||
|
import google.registry.flows.domain.DomainFlowUtils.ExceedsMaxRegistrationYearsException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesMismatchException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
import google.registry.flows.domain.DomainFlowUtils.FeesRequiredForPremiumNameException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
|
import google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
|
import google.registry.flows.domain.DomainFlowUtils.UnsupportedFeeAttributeException;
|
||||||
import google.registry.flows.domain.DomainRenewFlow.DomainHasPendingTransferException;
|
import google.registry.flows.domain.DomainRenewFlow.DomainHasPendingTransferException;
|
||||||
import google.registry.flows.domain.DomainRenewFlow.ExceedsMaxRegistrationYearsException;
|
|
||||||
import google.registry.flows.domain.DomainRenewFlow.IncorrectCurrentExpirationDateException;
|
import google.registry.flows.domain.DomainRenewFlow.IncorrectCurrentExpirationDateException;
|
||||||
import google.registry.flows.exceptions.ResourceStatusProhibitsOperationException;
|
import google.registry.flows.exceptions.ResourceStatusProhibitsOperationException;
|
||||||
import google.registry.model.billing.BillingEvent;
|
import google.registry.model.billing.BillingEvent;
|
||||||
|
|
24
javatests/google/registry/flows/domain/testdata/domain_allocate_11_years.xml
vendored
Normal file
24
javatests/google/registry/flows/domain/testdata/domain_allocate_11_years.xml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||||
|
<command>
|
||||||
|
<create>
|
||||||
|
<domain:create
|
||||||
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
|
<domain:name>example-one.tld</domain:name>
|
||||||
|
<domain:period unit="y">11</domain:period>
|
||||||
|
<domain:registrant>jd1234</domain:registrant>
|
||||||
|
<domain:contact type="admin">sh8013</domain:contact>
|
||||||
|
<domain:contact type="tech">sh8013</domain:contact>
|
||||||
|
<domain:authInfo>
|
||||||
|
<domain:pw>2fooBAR</domain:pw>
|
||||||
|
</domain:authInfo>
|
||||||
|
</domain:create>
|
||||||
|
</create>
|
||||||
|
<extension>
|
||||||
|
<allocate:create xmlns:allocate="urn:google:params:xml:ns:allocate-1.0">
|
||||||
|
<allocate:applicationRoid>2-TLD</allocate:applicationRoid>
|
||||||
|
<allocate:applicationTime>2010-08-16T10:00:00.0Z</allocate:applicationTime>
|
||||||
|
</allocate:create>
|
||||||
|
</extension>
|
||||||
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
</command>
|
||||||
|
</epp>
|
22
javatests/google/registry/flows/domain/testdata/domain_create_11_years.xml
vendored
Normal file
22
javatests/google/registry/flows/domain/testdata/domain_create_11_years.xml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||||
|
<command>
|
||||||
|
<create>
|
||||||
|
<domain:create
|
||||||
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
|
<domain:name>example.tld</domain:name>
|
||||||
|
<domain:period unit="y">11</domain:period>
|
||||||
|
<domain:ns>
|
||||||
|
<domain:hostObj>ns1.example.net</domain:hostObj>
|
||||||
|
<domain:hostObj>ns2.example.net</domain:hostObj>
|
||||||
|
</domain:ns>
|
||||||
|
<domain:registrant>jd1234</domain:registrant>
|
||||||
|
<domain:contact type="admin">sh8013</domain:contact>
|
||||||
|
<domain:contact type="tech">sh8013</domain:contact>
|
||||||
|
<domain:authInfo>
|
||||||
|
<domain:pw>2fooBAR</domain:pw>
|
||||||
|
</domain:authInfo>
|
||||||
|
</domain:create>
|
||||||
|
</create>
|
||||||
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
</command>
|
||||||
|
</epp>
|
29
javatests/google/registry/flows/domain/testdata/domain_create_landrush_11_years.xml
vendored
Normal file
29
javatests/google/registry/flows/domain/testdata/domain_create_landrush_11_years.xml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||||
|
<command>
|
||||||
|
<create>
|
||||||
|
<domain:create
|
||||||
|
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||||
|
<domain:name>test-validate.tld</domain:name>
|
||||||
|
<domain:period unit="y">11</domain:period>
|
||||||
|
<domain:ns>
|
||||||
|
<domain:hostObj>ns1.example.net</domain:hostObj>
|
||||||
|
<domain:hostObj>ns2.example.net</domain:hostObj>
|
||||||
|
</domain:ns>
|
||||||
|
<domain:registrant>jd1234</domain:registrant>
|
||||||
|
<domain:contact type="admin">sh8013</domain:contact>
|
||||||
|
<domain:contact type="tech">sh8013</domain:contact>
|
||||||
|
<domain:authInfo>
|
||||||
|
<domain:pw>2fooBAR</domain:pw>
|
||||||
|
</domain:authInfo>
|
||||||
|
</domain:create>
|
||||||
|
</create>
|
||||||
|
<extension>
|
||||||
|
<launch:create
|
||||||
|
xmlns:launch="urn:ietf:params:xml:ns:launch-1.0">
|
||||||
|
<launch:phase>landrush</launch:phase>
|
||||||
|
</launch:create>
|
||||||
|
</extension>
|
||||||
|
<clTRID>ABC-12345</clTRID>
|
||||||
|
</command>
|
||||||
|
</epp>
|
Loading…
Add table
Add a link
Reference in a new issue