Improve the error when trying to delete the registrant contact

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=196708902
This commit is contained in:
guyben 2018-05-15 12:13:39 -07:00 committed by jianglai
parent 25d03f239c
commit e4f25c08e8
5 changed files with 55 additions and 1 deletions

View file

@ -956,6 +956,7 @@ the domain to convert to a normal create and be billed for accordingly.
is not free. is not free.
* Admin contact is required. * Admin contact is required.
* Technical contact is required. * Technical contact is required.
* Registrant is required.
* 2004 * 2004
* The specified status value cannot be set by clients. * The specified status value cannot be set by clients.
* 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

View file

@ -59,6 +59,7 @@ import google.registry.flows.custom.DomainUpdateFlowCustomLogic;
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.AfterValidationParameters; import google.registry.flows.custom.DomainUpdateFlowCustomLogic.AfterValidationParameters;
import google.registry.flows.custom.DomainUpdateFlowCustomLogic.BeforeSaveParameters; import google.registry.flows.custom.DomainUpdateFlowCustomLogic.BeforeSaveParameters;
import google.registry.flows.custom.EntityChanges; import google.registry.flows.custom.EntityChanges;
import google.registry.flows.domain.DomainFlowUtils.MissingRegistrantException;
import google.registry.model.ImmutableObject; import google.registry.model.ImmutableObject;
import google.registry.model.billing.BillingEvent; import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason; import google.registry.model.billing.BillingEvent.Reason;
@ -117,6 +118,7 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.MissingAdminContactException} * @error {@link DomainFlowUtils.MissingAdminContactException}
* @error {@link DomainFlowUtils.MissingContactTypeException} * @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingTechnicalContactException} * @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.MissingRegistrantException}
* @error {@link DomainFlowUtils.NameserversNotAllowedForTldException} * @error {@link DomainFlowUtils.NameserversNotAllowedForTldException}
* @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverWhitelistException} * @error {@link DomainFlowUtils.NameserversNotSpecifiedForTldWithNameserverWhitelistException}
* @error {@link DomainFlowUtils.NameserversNotAllowedForDomainException} * @error {@link DomainFlowUtils.NameserversNotAllowedForDomainException}
@ -258,6 +260,7 @@ public final class DomainUpdateFlow implements TransactionalFlow {
checkSameValuesNotAddedAndRemoved(add.getContacts(), remove.getContacts()); checkSameValuesNotAddedAndRemoved(add.getContacts(), remove.getContacts());
checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues()); checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues());
Change change = command.getInnerChange(); Change change = command.getInnerChange();
validateRegistrantIsntBeingRemoved(change);
Optional<SecDnsUpdateExtension> secDnsUpdate = Optional<SecDnsUpdateExtension> secDnsUpdate =
eppInput.getSingleExtension(SecDnsUpdateExtension.class); eppInput.getSingleExtension(SecDnsUpdateExtension.class);
DomainResource.Builder domainBuilder = DomainResource.Builder domainBuilder =
@ -330,6 +333,12 @@ public final class DomainUpdateFlow implements TransactionalFlow {
.build(); .build();
} }
private void validateRegistrantIsntBeingRemoved(Change change) throws EppException {
if (change.getRegistrantContactId() != null && change.getRegistrantContactId().isEmpty()) {
throw new MissingRegistrantException();
}
}
private void validateNewState(DomainResource newDomain) throws EppException { private void validateNewState(DomainResource newDomain) throws EppException {
validateNoDuplicateContacts(newDomain.getContacts()); validateNoDuplicateContacts(newDomain.getContacts());
validateRequiredContactsPresent(newDomain.getRegistrant(), newDomain.getContacts()); validateRequiredContactsPresent(newDomain.getRegistrant(), newDomain.getContacts());

View file

@ -27,6 +27,7 @@ import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static google.registry.util.CollectionUtils.union; import static google.registry.util.CollectionUtils.union;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
@ -387,7 +388,7 @@ public class DomainCommand {
/** Creates a copy of this {@link Change} with hard links to hosts and contacts. */ /** Creates a copy of this {@link Change} with hard links to hosts and contacts. */
Change cloneAndLinkReferences(DateTime now) throws InvalidReferencesException { Change cloneAndLinkReferences(DateTime now) throws InvalidReferencesException {
Change clone = clone(this); Change clone = clone(this);
clone.registrant = clone.registrantContactId == null clone.registrant = Strings.isNullOrEmpty(clone.registrantContactId)
? null ? null
: getOnlyElement( : getOnlyElement(
loadByForeignKeys( loadByForeignKeys(

View file

@ -63,6 +63,7 @@ import google.registry.flows.domain.DomainFlowUtils.LinkedResourcesDoNotExistExc
import google.registry.flows.domain.DomainFlowUtils.MaxSigLifeChangeNotSupportedException; import google.registry.flows.domain.DomainFlowUtils.MaxSigLifeChangeNotSupportedException;
import google.registry.flows.domain.DomainFlowUtils.MissingAdminContactException; import google.registry.flows.domain.DomainFlowUtils.MissingAdminContactException;
import google.registry.flows.domain.DomainFlowUtils.MissingContactTypeException; import google.registry.flows.domain.DomainFlowUtils.MissingContactTypeException;
import google.registry.flows.domain.DomainFlowUtils.MissingRegistrantException;
import google.registry.flows.domain.DomainFlowUtils.MissingTechnicalContactException; import google.registry.flows.domain.DomainFlowUtils.MissingTechnicalContactException;
import google.registry.flows.domain.DomainFlowUtils.NameserversNotAllowedForDomainException; import google.registry.flows.domain.DomainFlowUtils.NameserversNotAllowedForDomainException;
import google.registry.flows.domain.DomainFlowUtils.NameserversNotAllowedForTldException; import google.registry.flows.domain.DomainFlowUtils.NameserversNotAllowedForTldException;
@ -185,6 +186,16 @@ public class DomainUpdateFlowTest extends ResourceFlowTestCase<DomainUpdateFlow,
doSuccessfulTest(); doSuccessfulTest();
} }
@Test
public void testFailure_emptyRegistrant() throws Exception {
setEppInput("domain_update_empty_registrant.xml");
persistReferencedEntities();
persistDomain();
MissingRegistrantException thrown =
assertThrows(MissingRegistrantException.class, this::runFlow);
assertAboutEppExceptions().that(thrown).marshalsToXml();
}
private void doSunrushAddTest( private void doSunrushAddTest(
BillingEvent.OneTime sunrushAddBillingEvent, BillingEvent.OneTime sunrushAddBillingEvent,
UserPrivileges userPrivileges, UserPrivileges userPrivileges,

View file

@ -0,0 +1,32 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<update>
<domain:update
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:add>
<domain:ns>
<domain:hostObj>ns2.example.foo</domain:hostObj>
</domain:ns>
<domain:contact type="tech">mak21</domain:contact>
<domain:status s="clientHold"
lang="en">Payment overdue.</domain:status>
</domain:add>
<domain:rem>
<domain:ns>
<domain:hostObj>ns1.example.foo</domain:hostObj>
</domain:ns>
<domain:contact type="tech">sh8013</domain:contact>
<domain:status s="clientUpdateProhibited"/>
</domain:rem>
<domain:chg>
<domain:registrant/>
<domain:authInfo>
<domain:pw>2BARfoo</domain:pw>
</domain:authInfo>
</domain:chg>
</domain:update>
</update>
<clTRID>ABC-12345</clTRID>
</command>
</epp>