Adds the ability to whitelist registrants and nameservers on a TLD

This is needed for ROCC TLDs like .foo
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=118404870
This commit is contained in:
cgoldfeder
2016-05-13 17:37:17 -04:00
committed by Justine Tunney
parent f9e1bab1d2
commit ec2daec412
17 changed files with 576 additions and 85 deletions
@@ -22,6 +22,7 @@ import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateDo
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateDsData;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateNameservers;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateNoDuplicateContacts;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateRegistrantAllowedOnTld;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateRequiredContactsPresent;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.verifyLaunchPhase;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
@@ -207,9 +208,10 @@ public abstract class BaseDomainCreateFlow<R extends DomainBase, B extends Build
command.getRegistrant(),
command.getNameservers());
validateContactsHaveTypes(command.getContacts());
validateRegistrantAllowedOnTld(tld, command.getRegistrant());
validateNoDuplicateContacts(command.getContacts());
validateRequiredContactsPresent(command.getRegistrant(), command.getContacts());
validateNameservers(command.getNameservers());
validateNameservers(tld, command.getNameservers());
validateLaunchCreateExtension();
// If a signed mark was provided, then it must match the desired domain label.
// We do this after validating the launch create extension so that flows which don't allow any
@@ -22,6 +22,7 @@ import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateCo
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateDsData;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateNameservers;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateNoDuplicateContacts;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateRegistrantAllowedOnTld;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.validateRequiredContactsPresent;
import static com.google.domain.registry.flows.domain.DomainFlowUtils.verifyNotInPendingDelete;
@@ -121,7 +122,8 @@ public abstract class BaseDomainUpdateFlow<R extends DomainBase, B extends Build
validateNoDuplicateContacts(newResource.getContacts());
validateRequiredContactsPresent(newResource.getRegistrant(), newResource.getContacts());
validateDsData(newResource.getDsData());
validateNameservers(newResource.getNameservers());
validateRegistrantAllowedOnTld(newResource.getTld(), newResource.getRegistrant());
validateNameservers(newResource.getTld(), newResource.getNameservers());
}
/** The secDNS:all element must have value 'true' if present. */
@@ -90,8 +90,10 @@ import java.util.List;
* @error {@link DomainFlowUtils.LeadingDashException}
* @error {@link DomainFlowUtils.LinkedResourceDoesNotExistException}
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.NameserverNotAllowedException}
* @error {@link DomainFlowUtils.NoMarksFoundMatchingDomainException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.SignedMarksMustBeEncodedException}
* @error {@link DomainFlowUtils.SignedMarkCertificateExpiredException}
* @error {@link DomainFlowUtils.SignedMarkCertificateInvalidException}
@@ -49,6 +49,8 @@ import com.google.domain.registry.model.reporting.HistoryEntry;
* @error {@link DomainFlowUtils.MissingAdminContactException}
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.NameserverNotAllowedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.TooManyDsRecordsException}
* @error {@link DomainFlowUtils.TooManyNameserversException}
* @error {@link DomainApplicationUpdateFlow.ApplicationStatusProhibitsUpdateException}
@@ -80,7 +80,9 @@ import java.util.Set;
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingRegistrantException}
* @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.NameserverNotAllowedException}
* @error {@link DomainFlowUtils.PremiumNameBlockedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.TldDoesNotExistException}
* @error {@link DomainFlowUtils.TooManyDsRecordsException}
* @error {@link DomainFlowUtils.TooManyNameserversException}
@@ -259,6 +259,7 @@ public class DomainFlowUtils {
private static void verifyNotInPendingDelete(
ReferenceUnion<? extends EppResource> resourceRef) throws EppException {
EppResource resource = resourceRef.getLinked().get();
if (resource.getStatusValues().contains(StatusValue.PENDING_DELETE)) {
throw new LinkedResourceInPendingDeleteProhibitsOperationException(resource.getForeignKey());
@@ -274,12 +275,26 @@ public class DomainFlowUtils {
}
}
static void validateNameservers(Set<ReferenceUnion<HostResource>> nameservers)
/** Return a foreign key for a {@link ReferenceUnion} from memory or datastore as needed. */
private static String resolveForeignKey(ReferenceUnion<?> ref) {
return Optional.fromNullable(ref.getForeignKey()).or(ref.getLinked().get().getForeignKey());
}
static void validateNameservers(String tld, Set<ReferenceUnion<HostResource>> nameservers)
throws EppException {
if (nameservers != null && nameservers.size() > MAX_NAMESERVERS_PER_DOMAIN) {
throw new TooManyNameserversException(String.format(
"Only %d nameservers are allowed per domain", MAX_NAMESERVERS_PER_DOMAIN));
}
ImmutableSet<String> whitelist = Registry.get(tld).getAllowedFullyQualifiedHostNames();
if (!whitelist.isEmpty()) { // Empty whitelists are ignored.
for (ReferenceUnion<HostResource> nameserver : nameservers) {
String foreignKey = resolveForeignKey(nameserver);
if (!whitelist.contains(foreignKey)) {
throw new NameserverNotAllowedException(foreignKey);
}
}
}
}
static void validateNoDuplicateContacts(Set<DesignatedContact> contacts)
@@ -311,6 +326,15 @@ public class DomainFlowUtils {
}
}
static void validateRegistrantAllowedOnTld(String tld, ReferenceUnion<ContactResource> registrant)
throws RegistrantNotAllowedException {
ImmutableSet<String> whitelist = Registry.get(tld).getAllowedRegistrantContactIds();
// Empty whitelists are ignored.
if (!whitelist.isEmpty() && !whitelist.contains(resolveForeignKey(registrant))) {
throw new RegistrantNotAllowedException(registrant.toString());
}
}
static void verifyNotReserved(
InternetDomainName domainName, boolean isSunriseApplication) throws EppException {
if (isReserved(domainName, isSunriseApplication)) {
@@ -963,4 +987,18 @@ public class DomainFlowUtils {
super("Registrar is not authorized to access the TLD " + tld);
}
}
/** Registrant is not whitelisted for this TLD. */
public static class RegistrantNotAllowedException extends StatusProhibitsOperationException {
public RegistrantNotAllowedException(String contactId) {
super(String.format("Registrant with id %s is not whitelisted for this TLD", contactId));
}
}
/** Nameserver is not whitelisted for this TLD. */
public static class NameserverNotAllowedException extends StatusProhibitsOperationException {
public NameserverNotAllowedException(String fullyQualifiedHostName) {
super(String.format("Nameserver %s is not whitelisted for this TLD", fullyQualifiedHostName));
}
}
}
@@ -60,6 +60,8 @@ import java.util.Set;
* @error {@link DomainFlowUtils.MissingAdminContactException}
* @error {@link DomainFlowUtils.MissingContactTypeException}
* @error {@link DomainFlowUtils.MissingTechnicalContactException}
* @error {@link DomainFlowUtils.NameserverNotAllowedException}
* @error {@link DomainFlowUtils.RegistrantNotAllowedException}
* @error {@link DomainFlowUtils.TooManyDsRecordsException}
* @error {@link DomainFlowUtils.TooManyNameserversException}
*/