diff --git a/java/google/registry/flows/domain/DomainApplicationInfoFlow.java b/java/google/registry/flows/domain/DomainApplicationInfoFlow.java index 97bb36917..f42e13843 100644 --- a/java/google/registry/flows/domain/DomainApplicationInfoFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationInfoFlow.java @@ -35,6 +35,7 @@ import google.registry.flows.FlowModule.ClientId; import google.registry.flows.FlowModule.TargetId; import google.registry.model.domain.DomainApplication; import google.registry.model.domain.DomainCommand.Info; +import google.registry.model.domain.flags.FlagsInfoResponseExtension; import google.registry.model.domain.launch.LaunchInfoExtension; import google.registry.model.domain.launch.LaunchInfoResponseExtension; import google.registry.model.eppcommon.AuthInfo; @@ -46,7 +47,9 @@ import google.registry.model.mark.Mark; import google.registry.model.smd.EncodedSignedMark; import google.registry.model.smd.SignedMark; import google.registry.util.Clock; +import java.util.Set; import javax.inject.Inject; +import org.joda.time.DateTime; /** * An EPP flow that returns information about a domain application. @@ -78,6 +81,7 @@ public final class DomainApplicationInfoFlow implements Flow { extensionManager.register(LaunchInfoExtension.class); extensionManager.validate(); validateClientIsLoggedIn(clientId); + DateTime now = clock.nowUtc(); if (applicationId.isEmpty()) { throw new MissingApplicationIdException(); } @@ -95,7 +99,7 @@ public final class DomainApplicationInfoFlow implements Flow { verifyResourceOwnership(clientId, application); return responseBuilder .setResData(getResourceInfo(application)) - .setExtensions(getDomainResponseExtensions(application, launchInfo)) + .setExtensions(getDomainResponseExtensions(application, launchInfo, now)) .build(); } @@ -111,8 +115,8 @@ public final class DomainApplicationInfoFlow implements Flow { return application; } - ImmutableList getDomainResponseExtensions( - DomainApplication application, LaunchInfoExtension launchInfo) { + ImmutableList getDomainResponseExtensions(DomainApplication application, + LaunchInfoExtension launchInfo, DateTime now) throws EppException { ImmutableList.Builder marksBuilder = new ImmutableList.Builder<>(); if (Boolean.TRUE.equals(launchInfo.getIncludeMark())) { // Default to false. for (EncodedSignedMark encodedMark : application.getEncodedSignedMarks()) { @@ -132,6 +136,16 @@ public final class DomainApplicationInfoFlow implements Flow { .setMarks(marksBuilder.build()) .build()); addSecDnsExtensionIfPresent(extensions, application.getDsData()); + // If the TLD uses the flags extension, add it to the info response. + Optional extraLogicManager = + RegistryExtraFlowLogicProxy.newInstanceForDomain(application); + if (extraLogicManager.isPresent()) { + Set flags = extraLogicManager.get().getApplicationExtensionFlags( + application, clientId, now); // As-of date is always now for info commands. + if (!flags.isEmpty()) { + extensions.add(FlagsInfoResponseExtension.create(ImmutableList.copyOf(flags))); + } + } return extensions.build(); } diff --git a/java/google/registry/flows/domain/RegistryExtraFlowLogic.java b/java/google/registry/flows/domain/RegistryExtraFlowLogic.java index 96e550fe9..5a63ea072 100644 --- a/java/google/registry/flows/domain/RegistryExtraFlowLogic.java +++ b/java/google/registry/flows/domain/RegistryExtraFlowLogic.java @@ -29,11 +29,11 @@ import org.joda.time.DateTime; */ public interface RegistryExtraFlowLogic { - /** - * Gets the flags to be used in the EPP flags extension. - * - *

This is used for EPP info commands. - */ + /** Gets the flags to be returned for application info commands. */ + public Set getApplicationExtensionFlags( + DomainApplication application, String clientId, DateTime asOfDate); + + /** Gets the flags to be returned for domain info commands. */ public Set getExtensionFlags( DomainResource domainResource, String clientId, DateTime asOfDate); diff --git a/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java b/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java index 9375ace74..bd15ed0ca 100644 --- a/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java @@ -37,6 +37,7 @@ import google.registry.model.domain.DesignatedContact; import google.registry.model.domain.DesignatedContact.Type; import google.registry.model.domain.DomainApplication; import google.registry.model.domain.DomainAuthInfo; +import google.registry.model.domain.TestExtraLogicManager; import google.registry.model.domain.launch.ApplicationStatus; import google.registry.model.domain.launch.LaunchCreateExtension; import google.registry.model.domain.launch.LaunchPhase; @@ -70,6 +71,9 @@ public class DomainApplicationInfoFlowTest setEppInput("domain_info_sunrise.xml"); sessionMetadata.setClientId("NewRegistrar"); createTld("tld", TldState.SUNRUSH); + createTld("flags", TldState.SUNRUSH); + // For flags extension tests. + RegistryExtraFlowLogicProxy.setOverride("flags", TestExtraLogicManager.class); } private void persistTestEntities(HostsState hostsState, MarksState marksState) throws Exception { @@ -107,6 +111,34 @@ public class DomainApplicationInfoFlowTest .build()); } + private void persistFlagsTestEntities(String domainName, HostsState hostsState) throws Exception { + registrant = persistActiveContact("jd1234"); + contact = persistActiveContact("sh8013"); + host1 = persistActiveHost("ns1.example.net"); + host2 = persistActiveHost("ns1.example.tld"); + application = persistResource(new DomainApplication.Builder() + .setRepoId("123-TLD") + .setFullyQualifiedDomainName(domainName) + .setPhase(LaunchPhase.SUNRUSH) + .setCurrentSponsorClientId("NewRegistrar") + .setCreationClientId("TheRegistrar") + .setLastEppUpdateClientId("NewRegistrar") + .setCreationTimeForTest(DateTime.parse("1999-04-03T22:00:00.0Z")) + .setLastEppUpdateTime(DateTime.parse("1999-12-03T09:00:00.0Z")) + .setLastTransferTime(DateTime.parse("2000-04-08T09:00:00.0Z")) + .setRegistrant(Key.create(registrant)) + .setContacts(ImmutableSet.of( + DesignatedContact.create(Type.ADMIN, Key.create(contact)), + DesignatedContact.create(Type.TECH, Key.create(contact)))) + .setNameservers(hostsState.equals(HostsState.HOSTS_EXIST) ? ImmutableSet.of( + Key.create(host1), Key.create(host2)) : null) + .setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("2fooBAR"))) + .addStatusValue(StatusValue.PENDING_CREATE) + .setApplicationStatus(ApplicationStatus.PENDING_VALIDATION) + .setEncodedSignedMarks(null) + .build()); + } + private void doSuccessfulTest(String expectedXmlFilename, HostsState hostsState) throws Exception { assertTransactionalFlow(false); @@ -318,4 +350,21 @@ public class DomainApplicationInfoFlowTest thrown.expect(ApplicationLaunchPhaseMismatchException.class); runFlow(); } + + + /** Test registry extra logic manager with no flags. */ + @Test + public void testExtraLogicManager_noFlags() throws Exception { + setEppInput("domain_info_sunrise_flags_none.xml"); + persistFlagsTestEntities("domain.flags", HostsState.NO_HOSTS_EXIST); + doSuccessfulTest("domain_info_response_sunrise_flags_none.xml", HostsState.NO_HOSTS_EXIST); + } + + /** Test registry extra logic manager with two flags. */ + @Test + public void testExtraLogicManager_twoFlags() throws Exception { + setEppInput("domain_info_sunrise_flags_two.xml"); + persistFlagsTestEntities("domain-flag1-flag2.flags", HostsState.NO_HOSTS_EXIST); + doSuccessfulTest("domain_info_response_sunrise_flags_two.xml", HostsState.NO_HOSTS_EXIST); + } } diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_none.xml b/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_none.xml new file mode 100644 index 000000000..7f9dfb42f --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_none.xml @@ -0,0 +1,37 @@ + + + + + Command completed successfully + + + + domain.flags + %ROID% + + jd1234 + sh8013 + sh8013 + NewRegistrar + TheRegistrar + 1999-04-03T22:00:00.0Z + NewRegistrar + 1999-12-03T09:00:00.0Z + + 2fooBAR + + + + + + sunrise + 123-TLD + + + + + ABC-12345 + server-trid + + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_two.xml b/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_two.xml new file mode 100644 index 000000000..c41567ccd --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_info_response_sunrise_flags_two.xml @@ -0,0 +1,41 @@ + + + + + Command completed successfully + + + + domain-flag1-flag2.flags + %ROID% + + jd1234 + sh8013 + sh8013 + NewRegistrar + TheRegistrar + 1999-04-03T22:00:00.0Z + NewRegistrar + 1999-12-03T09:00:00.0Z + + 2fooBAR + + + + + + sunrise + 123-TLD + + + + flag1 + flag2 + + + + ABC-12345 + server-trid + + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_none.xml b/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_none.xml new file mode 100644 index 000000000..85417598c --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_none.xml @@ -0,0 +1,19 @@ + + + + + + domain.flags + + + + + sunrise + 123-TLD + + + ABC-12345 + + diff --git a/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_two.xml b/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_two.xml new file mode 100644 index 000000000..261bd85a7 --- /dev/null +++ b/javatests/google/registry/flows/domain/testdata/domain_info_sunrise_flags_two.xml @@ -0,0 +1,19 @@ + + + + + + domain-flag1-flag2.flags + + + + + sunrise + 123-TLD + + + ABC-12345 + + diff --git a/javatests/google/registry/model/domain/TestExtraLogicManager.java b/javatests/google/registry/model/domain/TestExtraLogicManager.java index a03332355..73573aa5b 100644 --- a/javatests/google/registry/model/domain/TestExtraLogicManager.java +++ b/javatests/google/registry/model/domain/TestExtraLogicManager.java @@ -66,13 +66,30 @@ public class TestExtraLogicManager implements RegistryExtraFlowLogic { */ @Override public Set getExtensionFlags( - DomainResource domainResource, String clientId, DateTime asOfDate) { + DomainResource domain, String clientId, DateTime asOfDate) { // Take the part before the period, split by dashes, and treat each part after the first as // a flag. List components = Splitter.on('-').splitToList( Iterables.getFirst( - Splitter.on('.').split(domainResource.getFullyQualifiedDomainName()), "")); + Splitter.on('.').split(domain.getFullyQualifiedDomainName()), "")); + return ImmutableSet.copyOf(components.subList(1, components.size())); + } + + /** + * Gets the flags to be used in the EPP flags extension for application info commands. + * + *

This method works the same way as getExtensionFlags(). + */ + @Override + public Set getApplicationExtensionFlags( + DomainApplication application, String clientId, DateTime asOfDate) { + // Take the part before the period, split by dashes, and treat each part after the first as + // a flag. + List components = + Splitter.on('-').splitToList( + Iterables.getFirst( + Splitter.on('.').split(application.getFullyQualifiedDomainName()), "")); return ImmutableSet.copyOf(components.subList(1, components.size())); }