mirror of
https://github.com/google/nomulus.git
synced 2025-05-15 00:47:11 +02:00
Update create logic to ignore signed marks unless in sunrise
This addresses an issue where the existing logic assumed that the presence of a signed mark means the current flow is a sunrise/sunrush request, when this isn't necessarily true. It's safe to ignore signed marks in other circumstances. This is a combination of work by Justin Graham <justin.af.graham@gmail.com>, Nick Felt, and me (Ben). It is based on the original PR located at: https://github.com/google/nomulus/pull/41 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=140784461
This commit is contained in:
parent
59f4984083
commit
3740171bbf
7 changed files with 79 additions and 43 deletions
|
@ -27,3 +27,4 @@ Lai Jiang <jianglai@google.com>
|
||||||
Jordyn Buchanan <jordyn@google.com>
|
Jordyn Buchanan <jordyn@google.com>
|
||||||
Wolfgang Meyers <wolfgang@donuts.co>
|
Wolfgang Meyers <wolfgang@donuts.co>
|
||||||
Hans Ridder <hans.ridder@gmail.com>
|
Hans Ridder <hans.ridder@gmail.com>
|
||||||
|
Justin Graham <justin.af.graham@gmail.com>
|
||||||
|
|
|
@ -610,7 +610,6 @@ An EPP flow that creates a new domain resource.
|
||||||
|
|
||||||
* 2002
|
* 2002
|
||||||
* Service extension(s) must be declared at login.
|
* Service extension(s) must be declared at login.
|
||||||
* Signed marks are not accepted in the current registry phase.
|
|
||||||
* The current registry phase does not allow for general registrations.
|
* The current registry phase does not allow for general registrations.
|
||||||
* 2003
|
* 2003
|
||||||
* Fees must be explicitly acknowledged when performing any operations on a
|
* Fees must be explicitly acknowledged when performing any operations on a
|
||||||
|
|
|
@ -106,7 +106,6 @@ import org.joda.time.DateTime;
|
||||||
* @error {@link google.registry.flows.EppException.UnimplementedExtensionException}
|
* @error {@link google.registry.flows.EppException.UnimplementedExtensionException}
|
||||||
* @error {@link google.registry.flows.ExtensionManager.UndeclaredServiceExtensionException}
|
* @error {@link google.registry.flows.ExtensionManager.UndeclaredServiceExtensionException}
|
||||||
* @error {@link google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException}
|
* @error {@link google.registry.flows.domain.DomainFlowUtils.NotAuthorizedForTldException}
|
||||||
* @error {@link DomainCreateFlow.SignedMarksNotAcceptedInCurrentPhaseException}
|
|
||||||
* @error {@link DomainFlowUtils.AcceptedTooLongAgoException}
|
* @error {@link DomainFlowUtils.AcceptedTooLongAgoException}
|
||||||
* @error {@link DomainFlowUtils.BadDomainNameCharacterException}
|
* @error {@link DomainFlowUtils.BadDomainNameCharacterException}
|
||||||
* @error {@link DomainFlowUtils.BadDomainNamePartsCountException}
|
* @error {@link DomainFlowUtils.BadDomainNamePartsCountException}
|
||||||
|
@ -154,7 +153,7 @@ import org.joda.time.DateTime;
|
||||||
|
|
||||||
public class DomainCreateFlow implements TransactionalFlow {
|
public class DomainCreateFlow implements TransactionalFlow {
|
||||||
|
|
||||||
private static final Set<TldState> QLP_SMD_ALLOWED_STATES =
|
private static final Set<TldState> SUNRISE_STATES =
|
||||||
Sets.immutableEnumSet(TldState.SUNRISE, TldState.SUNRUSH);
|
Sets.immutableEnumSet(TldState.SUNRISE, TldState.SUNRUSH);
|
||||||
|
|
||||||
@Inject ExtensionManager extensionManager;
|
@Inject ExtensionManager extensionManager;
|
||||||
|
@ -202,9 +201,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
verifyNoCodeMarks(launchCreate);
|
verifyNoCodeMarks(launchCreate);
|
||||||
validateLaunchCreateNotice(launchCreate.getNotice(), domainLabel, isSuperuser, now);
|
validateLaunchCreateNotice(launchCreate.getNotice(), domainLabel, isSuperuser, now);
|
||||||
}
|
}
|
||||||
if (hasSignedMarks) {
|
boolean isSunriseCreate = hasSignedMarks && SUNRISE_STATES.contains(tldState);
|
||||||
verifySignedMarksAllowed(tldState, isAnchorTenant);
|
|
||||||
}
|
|
||||||
customLogic.afterValidation(
|
customLogic.afterValidation(
|
||||||
DomainCreateFlowCustomLogic.AfterValidationParameters.newBuilder()
|
DomainCreateFlowCustomLogic.AfterValidationParameters.newBuilder()
|
||||||
.setDomainName(domainName)
|
.setDomainName(domainName)
|
||||||
|
@ -226,7 +223,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
verifyLaunchPhaseMatchesRegistryPhase(registry, launchCreate, now);
|
verifyLaunchPhaseMatchesRegistryPhase(registry, launchCreate, now);
|
||||||
}
|
}
|
||||||
if (!isAnchorTenant) {
|
if (!isAnchorTenant) {
|
||||||
verifyNotReserved(domainName, hasSignedMarks);
|
verifyNotReserved(domainName, isSunriseCreate);
|
||||||
}
|
}
|
||||||
if (hasClaimsNotice) {
|
if (hasClaimsNotice) {
|
||||||
verifyClaimsPeriodNotEnded(registry, now);
|
verifyClaimsPeriodNotEnded(registry, now);
|
||||||
|
@ -293,7 +290,7 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
entitiesToSave.add(
|
entitiesToSave.add(
|
||||||
prepareMarkedLrpTokenEntity(authInfo.getPw().getValue(), domainName, historyEntry));
|
prepareMarkedLrpTokenEntity(authInfo.getPw().getValue(), domainName, historyEntry));
|
||||||
}
|
}
|
||||||
enqueueTasks(hasSignedMarks, hasClaimsNotice, newDomain);
|
enqueueTasks(isSunriseCreate, hasClaimsNotice, newDomain);
|
||||||
|
|
||||||
EntityChanges entityChanges =
|
EntityChanges entityChanges =
|
||||||
customLogic.beforeSave(
|
customLogic.beforeSave(
|
||||||
|
@ -324,14 +321,6 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
|| (metadataExtension != null && metadataExtension.getIsAnchorTenant());
|
|| (metadataExtension != null && metadataExtension.getIsAnchorTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Only QLP domains can have a signed mark on a domain create, and only in sunrise or sunrush. */
|
|
||||||
private void verifySignedMarksAllowed(TldState tldState, boolean isAnchorTenant)
|
|
||||||
throws SignedMarksNotAcceptedInCurrentPhaseException {
|
|
||||||
if (!isAnchorTenant || !QLP_SMD_ALLOWED_STATES.contains(tldState)) {
|
|
||||||
throw new SignedMarksNotAcceptedInCurrentPhaseException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Prohibit creating a domain if there is an open application for the same name. */
|
/** Prohibit creating a domain if there is an open application for the same name. */
|
||||||
private void verifyNoOpenApplications(DateTime now) throws DomainHasOpenApplicationsException {
|
private void verifyNoOpenApplications(DateTime now) throws DomainHasOpenApplicationsException {
|
||||||
for (DomainApplication application : loadActiveApplicationsByDomainName(targetId, now)) {
|
for (DomainApplication application : loadActiveApplicationsByDomainName(targetId, now)) {
|
||||||
|
@ -425,11 +414,11 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enqueueTasks(
|
private void enqueueTasks(
|
||||||
boolean hasSignedMarks, boolean hasClaimsNotice, DomainResource newDomain) {
|
boolean isSunriseCreate, boolean hasClaimsNotice, DomainResource newDomain) {
|
||||||
if (newDomain.shouldPublishToDns()) {
|
if (newDomain.shouldPublishToDns()) {
|
||||||
DnsQueue.create().addDomainRefreshTask(newDomain.getFullyQualifiedDomainName());
|
DnsQueue.create().addDomainRefreshTask(newDomain.getFullyQualifiedDomainName());
|
||||||
}
|
}
|
||||||
if (hasClaimsNotice || hasSignedMarks) {
|
if (hasClaimsNotice || isSunriseCreate) {
|
||||||
LordnTask.enqueueDomainResourceTask(newDomain);
|
LordnTask.enqueueDomainResourceTask(newDomain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,13 +437,6 @@ public class DomainCreateFlow implements TransactionalFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Signed marks are not accepted in the current registry phase. */
|
|
||||||
static class SignedMarksNotAcceptedInCurrentPhaseException extends CommandUseErrorException {
|
|
||||||
public SignedMarksNotAcceptedInCurrentPhaseException() {
|
|
||||||
super("Signed marks are not accepted in the current registry phase");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The current registry phase does not allow for general registrations. */
|
/** The current registry phase does not allow for general registrations. */
|
||||||
static class NoGeneralRegistrationsInCurrentPhaseException extends CommandUseErrorException {
|
static class NoGeneralRegistrationsInCurrentPhaseException extends CommandUseErrorException {
|
||||||
public NoGeneralRegistrationsInCurrentPhaseException() {
|
public NoGeneralRegistrationsInCurrentPhaseException() {
|
||||||
|
|
|
@ -366,18 +366,18 @@ public class DomainFlowUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verifyNotReserved(
|
static void verifyNotReserved(InternetDomainName domainName, boolean isSunrise)
|
||||||
InternetDomainName domainName, boolean isSunriseApplication) throws EppException {
|
throws EppException {
|
||||||
if (isReserved(domainName, isSunriseApplication)) {
|
if (isReserved(domainName, isSunrise)) {
|
||||||
throw new DomainReservedException(domainName.toString());
|
throw new DomainReservedException(domainName.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isReserved(InternetDomainName domainName, boolean inSunrise) {
|
private static boolean isReserved(InternetDomainName domainName, boolean isSunrise) {
|
||||||
ReservationType type = getReservationType(domainName);
|
ReservationType type = getReservationType(domainName);
|
||||||
return type == ReservationType.FULLY_BLOCKED
|
return type == ReservationType.FULLY_BLOCKED
|
||||||
|| type == ReservationType.RESERVED_FOR_ANCHOR_TENANT
|
|| type == ReservationType.RESERVED_FOR_ANCHOR_TENANT
|
||||||
|| (TYPES_ALLOWED_FOR_CREATE_ONLY_IN_SUNRISE.contains(type) && !inSunrise);
|
|| (TYPES_ALLOWED_FOR_CREATE_ONLY_IN_SUNRISE.contains(type) && !isSunrise);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns an enum that encodes how and when this name is reserved in the current tld. */
|
/** Returns an enum that encodes how and when this name is reserved in the current tld. */
|
||||||
|
|
|
@ -58,7 +58,6 @@ import google.registry.flows.ExtensionManager.UndeclaredServiceExtensionExceptio
|
||||||
import google.registry.flows.ResourceFlowTestCase;
|
import google.registry.flows.ResourceFlowTestCase;
|
||||||
import google.registry.flows.domain.DomainCreateFlow.DomainHasOpenApplicationsException;
|
import google.registry.flows.domain.DomainCreateFlow.DomainHasOpenApplicationsException;
|
||||||
import google.registry.flows.domain.DomainCreateFlow.NoGeneralRegistrationsInCurrentPhaseException;
|
import google.registry.flows.domain.DomainCreateFlow.NoGeneralRegistrationsInCurrentPhaseException;
|
||||||
import google.registry.flows.domain.DomainCreateFlow.SignedMarksNotAcceptedInCurrentPhaseException;
|
|
||||||
import google.registry.flows.domain.DomainFlowUtils.AcceptedTooLongAgoException;
|
import google.registry.flows.domain.DomainFlowUtils.AcceptedTooLongAgoException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.BadDomainNameCharacterException;
|
import google.registry.flows.domain.DomainFlowUtils.BadDomainNameCharacterException;
|
||||||
import google.registry.flows.domain.DomainFlowUtils.BadDomainNamePartsCountException;
|
import google.registry.flows.domain.DomainFlowUtils.BadDomainNamePartsCountException;
|
||||||
|
@ -123,6 +122,7 @@ import google.registry.model.reporting.HistoryEntry;
|
||||||
import google.registry.testing.DatastoreHelper;
|
import google.registry.testing.DatastoreHelper;
|
||||||
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
import google.registry.testing.TaskQueueHelper.TaskMatcher;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import org.joda.money.CurrencyUnit;
|
import org.joda.money.CurrencyUnit;
|
||||||
import org.joda.money.Money;
|
import org.joda.money.Money;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -252,9 +252,14 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNoLordn() throws Exception {
|
private void assertNoLordn() throws Exception {
|
||||||
|
assertNoLordn(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNoLordn(
|
||||||
|
@Nullable String smdId, @Nullable LaunchNotice launchNotice) throws Exception {
|
||||||
assertAboutDomains().that(reloadResourceByForeignKey())
|
assertAboutDomains().that(reloadResourceByForeignKey())
|
||||||
.hasSmdId(null).and()
|
.hasSmdId(smdId).and()
|
||||||
.hasLaunchNotice(null);
|
.hasLaunchNotice(launchNotice);
|
||||||
assertNoTasksEnqueued(QUEUE_CLAIMS, QUEUE_SUNRISE);
|
assertNoTasksEnqueued(QUEUE_CLAIMS, QUEUE_SUNRISE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +416,18 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
doSuccessfulTest();
|
doSuccessfulTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_generalAvailability_ignoresEncodedSignedMark() throws Exception {
|
||||||
|
createTld("tld", TldState.GENERAL_AVAILABILITY);
|
||||||
|
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
||||||
|
setEppInput("domain_create_registration_encoded_signed_mark.xml");
|
||||||
|
eppRequestSource = EppRequestSource.TOOL; // Only tools can pass in metadata.
|
||||||
|
persistContactsAndHosts();
|
||||||
|
runFlow();
|
||||||
|
assertSuccessfulCreate("tld", true);
|
||||||
|
assertNoLordn("0000001761376042759136-65535", null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_fee_v06() throws Exception {
|
public void testSuccess_fee_v06() throws Exception {
|
||||||
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
setEppInput("domain_create_fee.xml", ImmutableMap.of("FEE_VERSION", "0.6"));
|
||||||
|
@ -1210,10 +1227,11 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_signedMark() throws Exception {
|
public void testFailure_signedMarkWithoutAnchorTenant() throws Exception {
|
||||||
|
createTld("tld", TldState.SUNRISE);
|
||||||
setEppInput("domain_create_signed_mark.xml");
|
setEppInput("domain_create_signed_mark.xml");
|
||||||
persistContactsAndHosts();
|
persistContactsAndHosts();
|
||||||
thrown.expect(SignedMarksNotAcceptedInCurrentPhaseException.class);
|
thrown.expect(NoGeneralRegistrationsInCurrentPhaseException.class);
|
||||||
runFlow();
|
runFlow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1450,7 +1468,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_qlpSunriseRegistrationWithEncodedSignedMark() throws Exception {
|
public void testSuccess_qlpSunriseRegistration_withEncodedSignedMark() throws Exception {
|
||||||
createTld("tld", TldState.SUNRISE);
|
createTld("tld", TldState.SUNRISE);
|
||||||
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
||||||
setEppInput("domain_create_registration_qlp_sunrise_encoded_signed_mark.xml");
|
setEppInput("domain_create_registration_qlp_sunrise_encoded_signed_mark.xml");
|
||||||
|
@ -1462,7 +1480,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_qlpSunriseRegistrationWithClaimsNotice() throws Exception {
|
public void testSuccess_qlpSunriseRegistration_withClaimsNotice() throws Exception {
|
||||||
createTld("tld", TldState.SUNRISE);
|
createTld("tld", TldState.SUNRISE);
|
||||||
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
||||||
setEppInput("domain_create_registration_qlp_sunrise_claims_notice.xml");
|
setEppInput("domain_create_registration_qlp_sunrise_claims_notice.xml");
|
||||||
|
@ -1515,7 +1533,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_qlpSunrushRegistrationWithEncodedSignedMark() throws Exception {
|
public void testSuccess_qlpSunrushRegistration_withEncodedSignedMark() throws Exception {
|
||||||
createTld("tld", TldState.SUNRUSH);
|
createTld("tld", TldState.SUNRUSH);
|
||||||
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
||||||
setEppInput("domain_create_registration_qlp_sunrush_encoded_signed_mark.xml");
|
setEppInput("domain_create_registration_qlp_sunrush_encoded_signed_mark.xml");
|
||||||
|
@ -1527,7 +1545,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_qlpSunrushRegistrationWithClaimsNotice() throws Exception {
|
public void testSuccess_qlpSunrushRegistration_withClaimsNotice() throws Exception {
|
||||||
createTld("tld", TldState.SUNRUSH);
|
createTld("tld", TldState.SUNRUSH);
|
||||||
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
||||||
setEppInput("domain_create_registration_qlp_sunrush_claims_notice.xml");
|
setEppInput("domain_create_registration_qlp_sunrush_claims_notice.xml");
|
||||||
|
@ -1567,18 +1585,19 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFailure_qlpLandrushRegistrationWithEncodedSignedMark() throws Exception {
|
public void testSuccess_qlpLandrushRegistration_ignoresEncodedSignedMark() throws Exception {
|
||||||
createTld("tld", TldState.LANDRUSH);
|
createTld("tld", TldState.LANDRUSH);
|
||||||
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
clock.setTo(DateTime.parse("2014-09-09T09:09:09Z"));
|
||||||
setEppInput("domain_create_registration_qlp_landrush_encoded_signed_mark.xml");
|
setEppInput("domain_create_registration_qlp_landrush_encoded_signed_mark.xml");
|
||||||
eppRequestSource = EppRequestSource.TOOL; // Only tools can pass in metadata.
|
eppRequestSource = EppRequestSource.TOOL; // Only tools can pass in metadata.
|
||||||
persistContactsAndHosts();
|
persistContactsAndHosts();
|
||||||
thrown.expect(SignedMarksNotAcceptedInCurrentPhaseException.class);
|
|
||||||
runFlow();
|
runFlow();
|
||||||
|
assertSuccessfulCreate("tld", true);
|
||||||
|
assertNoLordn("0000001761376042759136-65535", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_qlpLandrushRegistrationWithClaimsNotice() throws Exception {
|
public void testSuccess_qlpLandrushRegistration_withClaimsNotice() throws Exception {
|
||||||
createTld("tld", TldState.LANDRUSH);
|
createTld("tld", TldState.LANDRUSH);
|
||||||
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
clock.setTo(DateTime.parse("2009-08-16T09:00:00.0Z"));
|
||||||
setEppInput("domain_create_registration_qlp_landrush_claims_notice.xml");
|
setEppInput("domain_create_registration_qlp_landrush_claims_notice.xml");
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,7 +21,7 @@
|
||||||
<launch:create
|
<launch:create
|
||||||
xmlns:launch="urn:ietf:params:xml:ns:launch-1.0"
|
xmlns:launch="urn:ietf:params:xml:ns:launch-1.0"
|
||||||
type="registration">
|
type="registration">
|
||||||
<launch:phase>claims</launch:phase>
|
<launch:phase>sunrise</launch:phase>
|
||||||
<smd:signedMark xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" id="signedMark">
|
<smd:signedMark xmlns:smd="urn:ietf:params:xml:ns:signedMark-1.0" id="signedMark">
|
||||||
<smd:id>1-2</smd:id>
|
<smd:id>1-2</smd:id>
|
||||||
<smd:issuerInfo issuerID="2">
|
<smd:issuerInfo issuerID="2">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue