mirror of
https://github.com/google/nomulus
synced 2026-02-07 05:21:15 +00:00
Remove contact as a supported object type in EPP (#2954)
This primarily affects the EPP greeting. We already were erroring out when any contact flows attempted to be run; this should just prevent registrars from even trying them at all. This PR is designed to be minimally invasive, and does not remove any of the contact flows or Jakarta XML/XJC objects/files themselves. That can be done later as a follow-up. Also note that the contact namespace urn:ietf:params:xml:ns:contact-1.0 is still present for now in RDE exports, but I'll remove that subsequently as well. This is a redo of PR #2932, which had been reverted, but now controlled via FeatureFlag so that it won't be enabled until we schedule it to do so (and only after sufficient time has passed after notifying registrars in advance). BUG= http://b/475506288
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package google.registry.flows.session;
|
||||
|
||||
import static com.google.common.collect.Sets.difference;
|
||||
import static google.registry.model.common.FeatureFlag.FeatureName.PROHIBIT_CONTACT_OBJECTS_ON_LOGIN;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.util.CollectionUtils.nullToEmpty;
|
||||
|
||||
@@ -39,6 +40,7 @@ import google.registry.flows.TlsCredentials.BadRegistrarIpAddressException;
|
||||
import google.registry.flows.TlsCredentials.MissingRegistrarCertificateException;
|
||||
import google.registry.flows.TransportCredentials;
|
||||
import google.registry.flows.TransportCredentials.BadRegistrarPasswordException;
|
||||
import google.registry.model.common.FeatureFlag;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition;
|
||||
import google.registry.model.eppcommon.ProtocolDefinition.ServiceExtension;
|
||||
import google.registry.model.eppinput.EppInput;
|
||||
@@ -114,9 +116,13 @@ public class LoginFlow implements MutatingFlow {
|
||||
}
|
||||
Services services = login.getServices();
|
||||
stopwatch.tick("LoginFlow getServices");
|
||||
Set<String> unsupportedObjectServices = difference(
|
||||
nullToEmpty(services.getObjectServices()),
|
||||
ProtocolDefinition.SUPPORTED_OBJECT_SERVICES);
|
||||
|
||||
Set<String> unsupportedObjectServices =
|
||||
difference(
|
||||
nullToEmpty(services.getObjectServices()),
|
||||
FeatureFlag.isActiveNow(PROHIBIT_CONTACT_OBJECTS_ON_LOGIN)
|
||||
? ProtocolDefinition.SUPPORTED_OBJECT_SERVICES
|
||||
: ProtocolDefinition.SUPPORTED_OBJECT_SERVICES_WITH_CONTACT);
|
||||
stopwatch.tick("LoginFlow difference unsupportedObjectServices");
|
||||
if (!unsupportedObjectServices.isEmpty()) {
|
||||
throw new UnimplementedObjectServiceException();
|
||||
|
||||
@@ -64,6 +64,7 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
|
||||
|
||||
/** The names of the feature flags that can be individually set. */
|
||||
public enum FeatureName {
|
||||
|
||||
/** Feature flag name used for testing only. */
|
||||
TEST_FEATURE(FeatureStatus.INACTIVE),
|
||||
|
||||
@@ -76,7 +77,10 @@ public class FeatureFlag extends ImmutableObject implements Buildable {
|
||||
/**
|
||||
* If we're including the upcoming domain drop date in the exported list of registered domains.
|
||||
*/
|
||||
INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS(FeatureStatus.INACTIVE);
|
||||
INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS(FeatureStatus.INACTIVE),
|
||||
|
||||
/** If we're prohibiting the inclusion of the contact object URI on login. */
|
||||
PROHIBIT_CONTACT_OBJECTS_ON_LOGIN(FeatureStatus.INACTIVE);
|
||||
|
||||
private final FeatureStatus defaultStatus;
|
||||
|
||||
|
||||
@@ -46,10 +46,13 @@ public class ProtocolDefinition {
|
||||
public static final String LANGUAGE = "en";
|
||||
|
||||
public static final ImmutableSet<String> SUPPORTED_OBJECT_SERVICES =
|
||||
ImmutableSet.of(
|
||||
"urn:ietf:params:xml:ns:host-1.0",
|
||||
"urn:ietf:params:xml:ns:domain-1.0",
|
||||
"urn:ietf:params:xml:ns:contact-1.0");
|
||||
ImmutableSet.of("urn:ietf:params:xml:ns:host-1.0", "urn:ietf:params:xml:ns:domain-1.0");
|
||||
|
||||
public static final ImmutableSet<String> SUPPORTED_OBJECT_SERVICES_WITH_CONTACT =
|
||||
new ImmutableSet.Builder<String>()
|
||||
.addAll(SUPPORTED_OBJECT_SERVICES)
|
||||
.add("urn:ietf:params:xml:ns:contact-1.0")
|
||||
.build();
|
||||
|
||||
/** Enum representing which environments should have which service extensions enabled. */
|
||||
private enum ServiceExtensionVisibility {
|
||||
|
||||
@@ -1151,7 +1151,6 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCase<DomainCheckFlow, Dom
|
||||
.marshalsToXml();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testSuccess_eapFeeCheck_std_v1() throws Exception {
|
||||
runEapFeeCheckTestWithXmlInputOutput(
|
||||
|
||||
@@ -16,14 +16,17 @@ package google.registry.flows.session;
|
||||
|
||||
import static com.google.common.io.BaseEncoding.base64;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.common.FeatureFlag.FeatureName.PROHIBIT_CONTACT_OBJECTS_ON_LOGIN;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
|
||||
import static google.registry.testing.DatabaseHelper.deleteResource;
|
||||
import static google.registry.testing.DatabaseHelper.loadRegistrar;
|
||||
import static google.registry.testing.DatabaseHelper.persistResource;
|
||||
import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions;
|
||||
import static google.registry.util.DateTimeUtils.START_OF_TIME;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import google.registry.flows.EppException;
|
||||
import google.registry.flows.EppException.UnimplementedExtensionException;
|
||||
import google.registry.flows.EppException.UnimplementedObjectServiceException;
|
||||
@@ -36,6 +39,8 @@ import google.registry.flows.session.LoginFlow.BadRegistrarIdException;
|
||||
import google.registry.flows.session.LoginFlow.RegistrarAccountNotActiveException;
|
||||
import google.registry.flows.session.LoginFlow.TooManyFailedLoginsException;
|
||||
import google.registry.flows.session.LoginFlow.UnsupportedLanguageException;
|
||||
import google.registry.model.common.FeatureFlag;
|
||||
import google.registry.model.common.FeatureFlag.FeatureStatus;
|
||||
import google.registry.model.eppoutput.EppOutput;
|
||||
import google.registry.model.registrar.Registrar;
|
||||
import google.registry.model.registrar.Registrar.State;
|
||||
@@ -56,6 +61,11 @@ public abstract class LoginFlowTestCase extends FlowTestCase<LoginFlow> {
|
||||
sessionMetadata.setRegistrarId(null); // Don't implicitly log in (all other flows need to).
|
||||
registrar = loadRegistrar("NewRegistrar");
|
||||
registrarBuilder = registrar.asBuilder();
|
||||
persistResource(
|
||||
new FeatureFlag.Builder()
|
||||
.setFeatureName(PROHIBIT_CONTACT_OBJECTS_ON_LOGIN)
|
||||
.setStatusMap(ImmutableSortedMap.of(START_OF_TIME, FeatureStatus.ACTIVE))
|
||||
.build());
|
||||
}
|
||||
|
||||
// Can't inline this since it may be overridden in subclasses.
|
||||
@@ -117,6 +127,21 @@ public abstract class LoginFlowTestCase extends FlowTestCase<LoginFlow> {
|
||||
doFailingTest("login_invalid_extension.xml", UnimplementedExtensionException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidContactObjectUri() {
|
||||
doFailingTest("login_with_contact_objuri.xml", UnimplementedObjectServiceException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_contactObjectUri_worksWhenNotProhibited() throws Exception {
|
||||
persistResource(
|
||||
FeatureFlag.get(PROHIBIT_CONTACT_OBJECTS_ON_LOGIN)
|
||||
.asBuilder()
|
||||
.setStatusMap(ImmutableSortedMap.of(START_OF_TIME, FeatureStatus.INACTIVE))
|
||||
.build());
|
||||
doSuccessfulTest("login_with_contact_objuri.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_invalidTypes() {
|
||||
doFailingTest("login_invalid_types.xml", UnimplementedObjectServiceException.class);
|
||||
|
||||
@@ -68,10 +68,7 @@ class EppInputTest {
|
||||
assertThat(loginCommand.options.version).isEqualTo("1.0");
|
||||
assertThat(loginCommand.options.language).isEqualTo("en");
|
||||
assertThat(loginCommand.services.objectServices)
|
||||
.containsExactly(
|
||||
"urn:ietf:params:xml:ns:host-1.0",
|
||||
"urn:ietf:params:xml:ns:domain-1.0",
|
||||
"urn:ietf:params:xml:ns:contact-1.0");
|
||||
.containsExactly("urn:ietf:params:xml:ns:host-1.0", "urn:ietf:params:xml:ns:domain-1.0");
|
||||
assertThat(loginCommand.services.serviceExtensions)
|
||||
.containsExactly("urn:ietf:params:xml:ns:launch-1.0", "urn:ietf:params:xml:ns:rgp-1.0");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<version>1.0</version>
|
||||
<lang>en</lang>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<version>1.0</version>
|
||||
<lang>en</lang>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>http://custom/obj1ext-1.0</extURI>
|
||||
</svcExtension>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:foo-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<login>
|
||||
<clID>NewRegistrar</clID>
|
||||
<pw>foo-BAR2</pw>
|
||||
<options>
|
||||
<version>1.0</version>
|
||||
<lang>en</lang>
|
||||
</options>
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>ABC-12345</clTRID>
|
||||
</command>
|
||||
</epp>
|
||||
@@ -12,7 +12,6 @@ xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
|
||||
</options>
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:secDNS-1.1</extURI>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
<extURI>urn:ietf:params:xml:ns:rgp-1.0</extURI>
|
||||
|
||||
@@ -467,7 +467,7 @@
|
||||
);
|
||||
|
||||
create table "FeatureFlag" (
|
||||
feature_name text not null check (feature_name in ('TEST_FEATURE','MINIMUM_DATASET_CONTACTS_OPTIONAL','MINIMUM_DATASET_CONTACTS_PROHIBITED','INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS')),
|
||||
feature_name text not null check (feature_name in ('TEST_FEATURE','MINIMUM_DATASET_CONTACTS_OPTIONAL','MINIMUM_DATASET_CONTACTS_PROHIBITED','INCLUDE_PENDING_DELETE_DATE_FOR_DOMAINS','PROHIBIT_CONTACT_OBJECTS_ON_LOGIN')),
|
||||
status hstore not null,
|
||||
primary key (feature_name)
|
||||
);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
</svcs>
|
||||
</login>
|
||||
<clTRID>epp-client-login-@@NOW@@-@@CHANNEL_NUMBER@@</clTRID>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<svcMenu>
|
||||
<version>1.0</version>
|
||||
<lang>en</lang>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
</svcMenu>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
</options>
|
||||
<svcs>
|
||||
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
|
||||
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
|
||||
<svcExtension>
|
||||
<extURI>urn:ietf:params:xml:ns:launch-1.0</extURI>
|
||||
|
||||
Reference in New Issue
Block a user