Add and wire up the AllocationTokenExtension XML class

The extension itself isn't used for anything yet; allocation tokens can be
passed for domain creates and checks but are ignored if present. This will
be changed in a subsequent CL that adds AllocationToken entities and related
logic. Usage of this extension in any other EPP flow will throw an
UnsupportedExtensionException.

The relevant spec is https://tools.ietf.org/html/draft-gould-allocation-token-04

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=181343188
This commit is contained in:
mcilwain 2018-01-09 11:00:05 -08:00 committed by Ben McIlwain
parent f6f43badd4
commit 5f62947691
14 changed files with 177 additions and 3 deletions

View file

@ -602,6 +602,8 @@ An EPP flow that deletes a domain.
* 2002
* Command is not allowed in the current registry phase.
* 2103
* Specified extension is not implemented.
* 2201
* The specified resource belongs to another client.
* Only a tool can pass a metadata extension.

View file

@ -64,7 +64,8 @@ public class EppXmlTransformer {
"smd.xsd",
"launch.xsd",
"allocate.xsd",
"superuser.xsd");
"superuser.xsd",
"allocationToken-1.0.xsd");
private static final XmlTransformer INPUT_TRANSFORMER =
new XmlTransformer(SCHEMAS, EppInput.class);

View file

@ -49,6 +49,7 @@ import google.registry.model.domain.fee.FeeCheckCommandExtension;
import google.registry.model.domain.fee.FeeCheckCommandExtensionItem;
import google.registry.model.domain.fee.FeeCheckResponseExtensionItem;
import google.registry.model.domain.launch.LaunchCheckExtension;
import google.registry.model.domain.token.AllocationTokenExtension;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.CheckData.DomainCheck;
@ -118,7 +119,8 @@ public final class DomainCheckFlow implements Flow {
@Override
public EppResponse run() throws EppException {
extensionManager.register(FeeCheckCommandExtension.class, LaunchCheckExtension.class);
extensionManager.register(
FeeCheckCommandExtension.class, LaunchCheckExtension.class, AllocationTokenExtension.class);
customLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);

View file

@ -85,6 +85,7 @@ import google.registry.model.domain.launch.LaunchCreateExtension;
import google.registry.model.domain.metadata.MetadataExtension;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.SecDnsCreateExtension;
import google.registry.model.domain.token.AllocationTokenExtension;
import google.registry.model.eppcommon.AuthInfo;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppinput.ResourceCommand;
@ -194,7 +195,8 @@ public class DomainCreateFlow implements TransactionalFlow {
FeeCreateCommandExtension.class,
SecDnsCreateExtension.class,
MetadataExtension.class,
LaunchCreateExtension.class);
LaunchCreateExtension.class,
AllocationTokenExtension.class);
customLogic.beforeValidation();
extensionManager.validate();
validateClientIsLoggedIn(clientId);

View file

@ -100,6 +100,7 @@ import org.joda.time.Duration;
/**
* An EPP flow that deletes a domain.
*
* @error {@link google.registry.flows.EppException.UnimplementedExtensionException}
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException}
* @error {@link google.registry.flows.ResourceFlowUtils.ResourceNotOwnedException}
* @error {@link google.registry.flows.exceptions.OnlyToolCanPassMetadataException}

View file

@ -0,0 +1,38 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.model.domain.token;
import google.registry.model.ImmutableObject;
import google.registry.model.eppinput.EppInput.CommandExtension;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
/**
* An allocation token extension that may be present on EPP domain commands.
*
* @see <a href="https://tools.ietf.org/html/draft-ietf-regext-allocation-token-04">the IETF
* draft</a> for full details.
*/
@XmlRootElement(name = "allocationToken")
public class AllocationTokenExtension extends ImmutableObject implements CommandExtension {
/** The allocation token for the command. */
@XmlValue
String allocationToken;
public String getAllocationToken() {
return allocationToken;
}
}

View file

@ -0,0 +1,31 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@XmlSchema(
namespace = "urn:ietf:params:xml:ns:allocationToken-1.0",
xmlns =
@XmlNs(
prefix = "allocationToken",
namespaceURI = "urn:ietf:params:xml:ns:allocationToken-1.0"
),
elementFormDefault = XmlNsForm.QUALIFIED
)
@XmlAccessorType(XmlAccessType.FIELD)
package google.registry.model.domain.token;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

View file

@ -51,6 +51,7 @@ import google.registry.model.domain.secdns.SecDnsCreateExtension;
import google.registry.model.domain.secdns.SecDnsUpdateExtension;
import google.registry.model.domain.superuser.DomainDeleteSuperuserExtension;
import google.registry.model.domain.superuser.DomainTransferRequestSuperuserExtension;
import google.registry.model.domain.token.AllocationTokenExtension;
import google.registry.model.eppinput.ResourceCommand.ResourceCheck;
import google.registry.model.eppinput.ResourceCommand.SingleResourceCommand;
import google.registry.model.host.HostCommand;
@ -329,6 +330,8 @@ public class EppInput extends ImmutableObject {
@XmlElementRefs({
// allocate create extension
@XmlElementRef(type = AllocateCreateExtension.class),
// allocation token extension
@XmlElementRef(type = AllocationTokenExtension.class),
// fee extension version 0.6
@XmlElementRef(type = FeeCheckCommandExtensionV06.class),
@XmlElementRef(type = FeeInfoCommandExtensionV06.class),

View file

@ -111,6 +111,17 @@ public class DomainCheckFlowTest
create(true, "example3.tld", null));
}
@Test
public void testSuccess_oneExists_allocationTokenDoesNothing() throws Exception {
// TODO(b/70628322): Change this test to fail on invalid allocationToken.
setEppInput("domain_check_allocationtoken.xml");
persistActiveDomain("example1.tld");
doCheckTest(
create(false, "example1.tld", "In use"),
create(true, "example2.tld", null),
create(true, "example3.tld", null));
}
@Test
public void testSuccess_oneReserved() throws Exception {
setEppInput("domain_check_one_tld_reserved.xml");

View file

@ -380,6 +380,14 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
doSuccessfulTest();
}
@Test
public void testSuccess_allocationToken_isIgnored() throws Exception {
// TODO(b/70628322): Change this test to fail on invalid allocationToken.
setEppInput("domain_create_allocationtoken.xml");
persistContactsAndHosts();
doSuccessfulTest();
}
@Test
public void testSuccess_multipartTld() throws Exception {
createTld("foo.tld");

View file

@ -54,6 +54,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException;
import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppRequestSource;
import google.registry.flows.ResourceFlowTestCase;
import google.registry.flows.ResourceFlowUtils.ResourceDoesNotExistException;
@ -1077,4 +1078,11 @@ public class DomainDeleteFlowTest extends ResourceFlowTestCase<DomainDeleteFlow,
CommitMode.LIVE, UserPrivileges.SUPERUSER, loadFile("domain_delete_response.xml"));
assertThat(reloadResourceByForeignKey()).isNull();
}
@Test
public void testFailure_allocationTokenNotSupportedOnDelete() throws Exception {
setEppInput("domain_delete_allocationtoken.xml");
EppException thrown = expectThrows(UnimplementedExtensionException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
}

View file

@ -0,0 +1,20 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<domain:check
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example1.tld</domain:name>
<domain:name>example2.tld</domain:name>
<domain:name>example3.tld</domain:name>
</domain:check>
</check>
<extension>
<allocationToken:allocationToken
xmlns:allocationToken=
"urn:ietf:params:xml:ns:allocationToken-1.0">
abc123
</allocationToken:allocationToken>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -0,0 +1,29 @@
<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">2</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>
<allocationToken:allocationToken
xmlns:allocationToken=
"urn:ietf:params:xml:ns:allocationToken-1.0">
abc123
</allocationToken:allocationToken>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View file

@ -0,0 +1,18 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<delete>
<domain:delete
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:delete>
</delete>
<extension>
<allocationToken:allocationToken
xmlns:allocationToken=
"urn:ietf:params:xml:ns:allocationToken-1.0">
abc123
</allocationToken:allocationToken>
</extension>
<clTRID>ABC-12345</clTRID>
</command>
</epp>