mirror of
https://github.com/google/nomulus.git
synced 2025-05-18 18:29:36 +02:00
RDAP: Add boilerplate entries required by ICANN RDAP Profile
The ICANN RDAP Profile (dated 3 December 2015) requires certain boilerplate entries at the top level of the JSON object. Specifically: 1.4.4. The terms of service of the RDAP service MUST be specified in the notices object in the topmost JSON object of the response. The notices object MUST contain a links object [RFC7483]. The links object MUST contain an URL of the contracted party providing the RDAP service. 1.4.10. An RDAP response MUST contain a remarks member with a description containing the string “This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0”. 1.5.18. A domain name RDAP response MUST contain a remarks member with a title “EPP Status Codes”, a description containing the string “For more information on domain status codes, please visit https://icann.org/epp” and a links member with the https://icann.org/epp URL. 1.5.20. A domain name RDAP response MUST contain a remarks member with a title “Whois Inaccuracy Complaint Form”, a description containing the string “URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf” and a links member with the https://www.icann.org/wicf URL. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=116389950
This commit is contained in:
parent
363c812d10
commit
ab26b288c1
29 changed files with 804 additions and 90 deletions
|
@ -80,9 +80,20 @@ public abstract class RdapActionBase implements Runnable {
|
||||||
/** Returns the servlet action path; used to extract the search string from the incoming path. */
|
/** Returns the servlet action path; used to extract the search string from the incoming path. */
|
||||||
abstract String getActionPath();
|
abstract String getActionPath();
|
||||||
|
|
||||||
/** Does the actual search and returns an RDAP JSON object. */
|
/**
|
||||||
abstract ImmutableMap<String, Object> getJsonObjectForResource(String searchString)
|
* Does the actual search and returns an RDAP JSON object.
|
||||||
throws HttpException;
|
*
|
||||||
|
* @param pathSearchString the search string in the URL path
|
||||||
|
* @param isHeadRequest whether the returned map will actually be used. HTTP HEAD requests don't
|
||||||
|
* actually return anything. However, we usually still want to go through the process of
|
||||||
|
* building a map, to make sure that the request would return a 500 status if it were
|
||||||
|
* invoked using GET. So this field should usually be ignored, unless there's some
|
||||||
|
* expensive task required to create the map which will never result in a request failure.
|
||||||
|
* @param linkBase the base URL for RDAP link structures
|
||||||
|
* @return A map (probably containing nested maps and lists) with the final JSON response data.
|
||||||
|
*/
|
||||||
|
abstract ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -98,11 +109,13 @@ public abstract class RdapActionBase implements Runnable {
|
||||||
pathProper.startsWith(getActionPath()),
|
pathProper.startsWith(getActionPath()),
|
||||||
"%s doesn't start with %s", pathProper, getActionPath());
|
"%s doesn't start with %s", pathProper, getActionPath());
|
||||||
ImmutableMap<String, Object> rdapJson =
|
ImmutableMap<String, Object> rdapJson =
|
||||||
getJsonObjectForResource(pathProper.substring(getActionPath().length()));
|
getJsonObjectForResource(
|
||||||
|
pathProper.substring(getActionPath().length()),
|
||||||
|
requestMethod == Action.Method.HEAD,
|
||||||
|
rdapLinkBase);
|
||||||
response.setStatus(SC_OK);
|
response.setStatus(SC_OK);
|
||||||
if (requestMethod != Action.Method.HEAD) {
|
if (requestMethod != Action.Method.HEAD) {
|
||||||
response.setPayload(
|
response.setPayload(JSONValue.toJSONString(rdapJson));
|
||||||
JSONValue.toJSONString(RdapJsonFormatter.makeFinalRdapJson(rdapJson)));
|
|
||||||
}
|
}
|
||||||
response.setContentType(MediaType.create("application", "rdap+json"));
|
response.setContentType(MediaType.create("application", "rdap+json"));
|
||||||
} catch (HttpException e) {
|
} catch (HttpException e) {
|
||||||
|
|
|
@ -48,8 +48,8 @@ public class RdapAutnumAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String pathSearchString)
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
throw new NotImplementedException("Domain Name Registry information only");
|
throw new NotImplementedException("Domain Name Registry information only");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ public class RdapDomainAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String pathSearchString)
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
pathSearchString = canonicalizeName(pathSearchString);
|
pathSearchString = canonicalizeName(pathSearchString);
|
||||||
validateDomainName(pathSearchString);
|
validateDomainName(pathSearchString);
|
||||||
// The query string is not used; the RDAP syntax is /rdap/domain/mydomain.com.
|
// The query string is not used; the RDAP syntax is /rdap/domain/mydomain.com.
|
||||||
|
@ -59,6 +59,7 @@ public class RdapDomainAction extends RdapActionBase {
|
||||||
if (domainResource == null) {
|
if (domainResource == null) {
|
||||||
throw new NotFoundException(pathSearchString + " not found");
|
throw new NotFoundException(pathSearchString + " not found");
|
||||||
}
|
}
|
||||||
return RdapJsonFormatter.makeRdapJsonForDomain(domainResource, rdapLinkBase, rdapWhoisServer);
|
return RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
|
domainResource, true, rdapLinkBase, rdapWhoisServer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.google.common.collect.Iterables;
|
||||||
import com.google.common.primitives.Booleans;
|
import com.google.common.primitives.Booleans;
|
||||||
import com.google.domain.registry.model.domain.DomainResource;
|
import com.google.domain.registry.model.domain.DomainResource;
|
||||||
import com.google.domain.registry.model.host.HostResource;
|
import com.google.domain.registry.model.host.HostResource;
|
||||||
|
import com.google.domain.registry.rdap.RdapJsonFormatter.BoilerplateType;
|
||||||
import com.google.domain.registry.request.Action;
|
import com.google.domain.registry.request.Action;
|
||||||
import com.google.domain.registry.request.HttpException;
|
import com.google.domain.registry.request.HttpException;
|
||||||
import com.google.domain.registry.request.HttpException.BadRequestException;
|
import com.google.domain.registry.request.HttpException.BadRequestException;
|
||||||
|
@ -82,8 +83,8 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
|
|
||||||
/** Parses the parameters and calls the appropriate search function. */
|
/** Parses the parameters and calls the appropriate search function. */
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object>
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
getJsonObjectForResource(final String pathSearchString) throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
DateTime now = clock.nowUtc();
|
DateTime now = clock.nowUtc();
|
||||||
// RDAP syntax example: /rdap/domains?name=exam*.com.
|
// RDAP syntax example: /rdap/domains?name=exam*.com.
|
||||||
// The pathSearchString is not used by search commands.
|
// The pathSearchString is not used by search commands.
|
||||||
|
@ -122,7 +123,10 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
throw new NotFoundException("No domains found");
|
throw new NotFoundException("No domains found");
|
||||||
}
|
}
|
||||||
return ImmutableMap.<String, Object>of("domainSearchResults", results);
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
|
builder.put("domainSearchResults", results);
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(builder, BoilerplateType.DOMAIN, null, rdapLinkBase);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for domains by domain name, returning a JSON array of domain info maps. */
|
/** Searches for domains by domain name, returning a JSON array of domain info maps. */
|
||||||
|
@ -136,7 +140,8 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
return ImmutableList.of(
|
return ImmutableList.of(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(domainResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
|
domainResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
// Handle queries with a wildcard.
|
// Handle queries with a wildcard.
|
||||||
} else {
|
} else {
|
||||||
Query<DomainResource> query = ofy().load()
|
Query<DomainResource> query = ofy().load()
|
||||||
|
@ -153,7 +158,7 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
if (domainResource.getDeletionTime().isAfter(now)) {
|
if (domainResource.getDeletionTime().isAfter(now)) {
|
||||||
builder.add(
|
builder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
domainResource, rdapLinkBase, rdapWhoisServer));
|
domainResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
@ -262,7 +267,8 @@ public class RdapDomainSearchAction extends RdapActionBase {
|
||||||
.limit(1000);
|
.limit(1000);
|
||||||
for (DomainResource domainResource : query) {
|
for (DomainResource domainResource : query) {
|
||||||
builder.add(
|
builder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(domainResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
|
domainResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.domain.registry.model.contact.ContactResource;
|
||||||
import com.google.domain.registry.model.domain.DesignatedContact;
|
import com.google.domain.registry.model.domain.DesignatedContact;
|
||||||
import com.google.domain.registry.model.registrar.Registrar;
|
import com.google.domain.registry.model.registrar.Registrar;
|
||||||
import com.google.domain.registry.request.Action;
|
import com.google.domain.registry.request.Action;
|
||||||
|
import com.google.domain.registry.request.HttpException;
|
||||||
import com.google.domain.registry.request.HttpException.BadRequestException;
|
import com.google.domain.registry.request.HttpException.BadRequestException;
|
||||||
import com.google.domain.registry.request.HttpException.NotFoundException;
|
import com.google.domain.registry.request.HttpException.NotFoundException;
|
||||||
import com.google.domain.registry.util.Clock;
|
import com.google.domain.registry.util.Clock;
|
||||||
|
@ -58,7 +59,8 @@ public class RdapEntityAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String pathSearchString) {
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
// The query string is not used; the RDAP syntax is /rdap/entity/handle (the handle is the roid
|
// The query string is not used; the RDAP syntax is /rdap/entity/handle (the handle is the roid
|
||||||
// for contacts and the client identifier for registrars). Since RDAP's concept of an entity
|
// for contacts and the client identifier for registrars). Since RDAP's concept of an entity
|
||||||
// includes both contacts and registrars, search for one first, then the other.
|
// includes both contacts and registrars, search for one first, then the other.
|
||||||
|
@ -70,6 +72,7 @@ public class RdapEntityAction extends RdapActionBase {
|
||||||
if ((contactResource != null) && clock.nowUtc().isBefore(contactResource.getDeletionTime())) {
|
if ((contactResource != null) && clock.nowUtc().isBefore(contactResource.getDeletionTime())) {
|
||||||
return RdapJsonFormatter.makeRdapJsonForContact(
|
return RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResource,
|
contactResource,
|
||||||
|
true,
|
||||||
Optional.<DesignatedContact.Type>absent(),
|
Optional.<DesignatedContact.Type>absent(),
|
||||||
rdapLinkBase,
|
rdapLinkBase,
|
||||||
rdapWhoisServer);
|
rdapWhoisServer);
|
||||||
|
@ -80,7 +83,8 @@ public class RdapEntityAction extends RdapActionBase {
|
||||||
wasValidKey = true;
|
wasValidKey = true;
|
||||||
Registrar registrar = Registrar.loadByClientId(clientId);
|
Registrar registrar = Registrar.loadByClientId(clientId);
|
||||||
if ((registrar != null) && registrar.isActiveAndPubliclyVisible()) {
|
if ((registrar != null) && registrar.isActiveAndPubliclyVisible()) {
|
||||||
return RdapJsonFormatter.makeRdapJsonForRegistrar(registrar, rdapLinkBase, rdapWhoisServer);
|
return RdapJsonFormatter.makeRdapJsonForRegistrar(
|
||||||
|
registrar, true, rdapLinkBase, rdapWhoisServer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw !wasValidKey
|
throw !wasValidKey
|
||||||
|
|
|
@ -27,6 +27,7 @@ import com.google.domain.registry.config.ConfigModule.Config;
|
||||||
import com.google.domain.registry.model.contact.ContactResource;
|
import com.google.domain.registry.model.contact.ContactResource;
|
||||||
import com.google.domain.registry.model.domain.DesignatedContact;
|
import com.google.domain.registry.model.domain.DesignatedContact;
|
||||||
import com.google.domain.registry.model.registrar.Registrar;
|
import com.google.domain.registry.model.registrar.Registrar;
|
||||||
|
import com.google.domain.registry.rdap.RdapJsonFormatter.BoilerplateType;
|
||||||
import com.google.domain.registry.request.Action;
|
import com.google.domain.registry.request.Action;
|
||||||
import com.google.domain.registry.request.HttpException;
|
import com.google.domain.registry.request.HttpException;
|
||||||
import com.google.domain.registry.request.HttpException.BadRequestException;
|
import com.google.domain.registry.request.HttpException.BadRequestException;
|
||||||
|
@ -76,8 +77,8 @@ public class RdapEntitySearchAction extends RdapActionBase {
|
||||||
|
|
||||||
/** Parses the parameters and calls the appropriate search function. */
|
/** Parses the parameters and calls the appropriate search function. */
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object>
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
getJsonObjectForResource(final String pathSearchString) throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
// RDAP syntax example: /rdap/entities?fn=Bobby%20Joe*.
|
// RDAP syntax example: /rdap/entities?fn=Bobby%20Joe*.
|
||||||
// The pathSearchString is not used by search commands.
|
// The pathSearchString is not used by search commands.
|
||||||
if (pathSearchString.length() > 0) {
|
if (pathSearchString.length() > 0) {
|
||||||
|
@ -97,7 +98,10 @@ public class RdapEntitySearchAction extends RdapActionBase {
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
throw new NotFoundException("No entities found");
|
throw new NotFoundException("No entities found");
|
||||||
}
|
}
|
||||||
return ImmutableMap.<String, Object>of("entitySearchResults", results);
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
|
builder.put("entitySearchResults", results);
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(builder, BoilerplateType.OTHER, null, rdapLinkBase);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for entities by handle, returning a JSON array of entity info maps. */
|
/** Searches for entities by handle, returning a JSON array of entity info maps. */
|
||||||
|
@ -114,13 +118,14 @@ public class RdapEntitySearchAction extends RdapActionBase {
|
||||||
if ((contactResource != null) && contactResource.getDeletionTime().isEqual(END_OF_TIME)) {
|
if ((contactResource != null) && contactResource.getDeletionTime().isEqual(END_OF_TIME)) {
|
||||||
builder.add(RdapJsonFormatter.makeRdapJsonForContact(
|
builder.add(RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResource,
|
contactResource,
|
||||||
|
false,
|
||||||
Optional.<DesignatedContact.Type>absent(),
|
Optional.<DesignatedContact.Type>absent(),
|
||||||
rdapLinkBase,
|
rdapLinkBase,
|
||||||
rdapWhoisServer));
|
rdapWhoisServer));
|
||||||
}
|
}
|
||||||
if ((registrar != null) && registrar.isActiveAndPubliclyVisible()) {
|
if ((registrar != null) && registrar.isActiveAndPubliclyVisible()) {
|
||||||
builder.add(RdapJsonFormatter.makeRdapJsonForRegistrar(
|
builder.add(RdapJsonFormatter.makeRdapJsonForRegistrar(
|
||||||
registrar, rdapLinkBase, rdapWhoisServer));
|
registrar, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
// Handle queries with a wildcard, but no suffix. For contact resources, the deletion time will
|
// Handle queries with a wildcard, but no suffix. For contact resources, the deletion time will
|
||||||
|
@ -139,6 +144,7 @@ public class RdapEntitySearchAction extends RdapActionBase {
|
||||||
for (ContactResource contactResource : query) {
|
for (ContactResource contactResource : query) {
|
||||||
builder.add(RdapJsonFormatter.makeRdapJsonForContact(
|
builder.add(RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResource,
|
contactResource,
|
||||||
|
false,
|
||||||
Optional.<DesignatedContact.Type>absent(),
|
Optional.<DesignatedContact.Type>absent(),
|
||||||
rdapLinkBase,
|
rdapLinkBase,
|
||||||
rdapWhoisServer));
|
rdapWhoisServer));
|
||||||
|
@ -150,7 +156,7 @@ public class RdapEntitySearchAction extends RdapActionBase {
|
||||||
rdapResultSetMaxSize)) {
|
rdapResultSetMaxSize)) {
|
||||||
if (registrar.isActiveAndPubliclyVisible()) {
|
if (registrar.isActiveAndPubliclyVisible()) {
|
||||||
builder.add(RdapJsonFormatter.makeRdapJsonForRegistrar(
|
builder.add(RdapJsonFormatter.makeRdapJsonForRegistrar(
|
||||||
registrar, rdapLinkBase, rdapWhoisServer));
|
registrar, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// In theory, there could be more results than our max size, so limit the size.
|
// In theory, there could be more results than our max size, so limit the size.
|
||||||
|
|
|
@ -19,6 +19,7 @@ import static com.google.domain.registry.request.Action.Method.HEAD;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.domain.registry.rdap.RdapJsonFormatter.BoilerplateType;
|
||||||
import com.google.domain.registry.rdap.RdapJsonFormatter.MakeRdapJsonNoticeParameters;
|
import com.google.domain.registry.rdap.RdapJsonFormatter.MakeRdapJsonNoticeParameters;
|
||||||
import com.google.domain.registry.request.Action;
|
import com.google.domain.registry.request.Action;
|
||||||
import com.google.domain.registry.request.HttpException;
|
import com.google.domain.registry.request.HttpException;
|
||||||
|
@ -36,6 +37,16 @@ public class RdapHelpAction extends RdapActionBase {
|
||||||
|
|
||||||
public static final String PATH = "/rdap/help";
|
public static final String PATH = "/rdap/help";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path for the terms of service. The terms of service are also used to create the required
|
||||||
|
* boilerplate notice, so we make it a publicly visible that we can use elsewhere to reference it.
|
||||||
|
*/
|
||||||
|
public static final String TERMS_OF_SERVICE_PATH = "/tos";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map from a relative path underneath the RDAP root path to the appropriate
|
||||||
|
* {@link MakeRdapJsonNoticeParameters} object.
|
||||||
|
*/
|
||||||
private static final ImmutableMap<String, MakeRdapJsonNoticeParameters> HELP_MAP =
|
private static final ImmutableMap<String, MakeRdapJsonNoticeParameters> HELP_MAP =
|
||||||
ImmutableMap.of(
|
ImmutableMap.of(
|
||||||
"/",
|
"/",
|
||||||
|
@ -76,7 +87,7 @@ public class RdapHelpAction extends RdapActionBase {
|
||||||
.linkValueSuffix("help/syntax")
|
.linkValueSuffix("help/syntax")
|
||||||
.linkHrefUrlString("https://www.registry.google/about/rdap/syntax.html")
|
.linkHrefUrlString("https://www.registry.google/about/rdap/syntax.html")
|
||||||
.build(),
|
.build(),
|
||||||
"/tos",
|
TERMS_OF_SERVICE_PATH,
|
||||||
MakeRdapJsonNoticeParameters.builder()
|
MakeRdapJsonNoticeParameters.builder()
|
||||||
.title("RDAP Terms of Service")
|
.title("RDAP Terms of Service")
|
||||||
.description(ImmutableList.of(
|
.description(ImmutableList.of(
|
||||||
|
@ -119,8 +130,21 @@ public class RdapHelpAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String pathSearchString)
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
|
// We rely on addTopLevelEntries to notice if we are sending the TOS notice, and not add a
|
||||||
|
// duplicate boilerplate entry.
|
||||||
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
BoilerplateType.OTHER,
|
||||||
|
ImmutableList.of(getJsonHelpNotice(pathSearchString, rdapLinkBase)),
|
||||||
|
rdapLinkBase);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImmutableMap<String, Object> getJsonHelpNotice(
|
||||||
|
String pathSearchString, String rdapLinkBase) {
|
||||||
if (pathSearchString.isEmpty()) {
|
if (pathSearchString.isEmpty()) {
|
||||||
pathSearchString = "/";
|
pathSearchString = "/";
|
||||||
}
|
}
|
||||||
|
@ -128,10 +152,8 @@ public class RdapHelpAction extends RdapActionBase {
|
||||||
throw new NotFoundException("no help found for " + pathSearchString);
|
throw new NotFoundException("no help found for " + pathSearchString);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return ImmutableMap.of(
|
return RdapJsonFormatter.makeRdapJsonNotice(
|
||||||
"notices",
|
HELP_MAP.get(pathSearchString), rdapLinkBase);
|
||||||
(Object) ImmutableList.of(RdapJsonFormatter.makeRdapJsonNotice(
|
|
||||||
HELP_MAP.get(pathSearchString), rdapLinkBase)));
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InternalServerErrorException("unable to read help for " + pathSearchString);
|
throw new InternalServerErrorException("unable to read help for " + pathSearchString);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2016 Google Inc. 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 com.google.domain.registry.rdap;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains boilerplate required by the ICANN RDAP Profile.
|
||||||
|
*
|
||||||
|
* @see "https://whois.icann.org/sites/default/files/files/gtld-rdap-operational-profile-draft-03dec15-en.pdf"
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RdapIcannStandardInformation {
|
||||||
|
|
||||||
|
/** Required by ICANN RDAP Profile section 1.4.10. */
|
||||||
|
private static final ImmutableMap<String, Object> CONFORMANCE_REMARK =
|
||||||
|
ImmutableMap.<String, Object>of(
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and"
|
||||||
|
+ " Registrars version 1.0"));
|
||||||
|
|
||||||
|
/** Required by ICANN RDAP Profile section 1.5.18. */
|
||||||
|
private static final ImmutableMap<String, Object> DOMAIN_STATUS_CODES_REMARK =
|
||||||
|
ImmutableMap.<String, Object> of(
|
||||||
|
"title",
|
||||||
|
"EPP Status Codes",
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"For more information on domain status codes, please visit https://icann.org/epp"),
|
||||||
|
"links",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"value", "https://icann.org/epp",
|
||||||
|
"rel", "alternate",
|
||||||
|
"href", "https://icann.org/epp",
|
||||||
|
"type", "text/html")));
|
||||||
|
|
||||||
|
/** Required by ICANN RDAP Profile section 1.5.20. */
|
||||||
|
private static final ImmutableMap<String, Object> INACCURACY_COMPLAINT_FORM_REMARK =
|
||||||
|
ImmutableMap.<String, Object> of(
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf"),
|
||||||
|
"links",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"value", "https://www.icann.org/wicf",
|
||||||
|
"rel", "alternate",
|
||||||
|
"href", "https://www.icann.org/wicf",
|
||||||
|
"type", "text/html")));
|
||||||
|
|
||||||
|
/** Boilerplate remarks required by domain responses. */
|
||||||
|
static final ImmutableList<ImmutableMap<String, Object>> domainBoilerplateRemarks =
|
||||||
|
ImmutableList.of(
|
||||||
|
CONFORMANCE_REMARK, DOMAIN_STATUS_CODES_REMARK, INACCURACY_COMPLAINT_FORM_REMARK);
|
||||||
|
|
||||||
|
/** Boilerplate remarks required by non-domain responses. */
|
||||||
|
static final ImmutableList<ImmutableMap<String, Object>> nonDomainBoilerplateRemarks =
|
||||||
|
ImmutableList.of(CONFORMANCE_REMARK);
|
||||||
|
}
|
|
@ -49,8 +49,8 @@ public class RdapIpAction extends RdapActionBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String pathSearchString)
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
throw new NotImplementedException("Domain Name Registry information only");
|
throw new NotImplementedException("Domain Name Registry information only");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,8 +72,20 @@ import javax.annotation.Nullable;
|
||||||
*/
|
*/
|
||||||
public class RdapJsonFormatter {
|
public class RdapJsonFormatter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What type of boilerplate notices are required for the RDAP JSON messages? The ICANN RDAP
|
||||||
|
* Profile specifies that, for instance, domain name responses should include a remark about
|
||||||
|
* domain status codes. So we need to know when to include such boilerplate.
|
||||||
|
*/
|
||||||
|
public enum BoilerplateType {
|
||||||
|
DOMAIN,
|
||||||
|
OTHER
|
||||||
|
}
|
||||||
|
|
||||||
private static final String RDAP_CONFORMANCE_LEVEL = "rdap_level_0";
|
private static final String RDAP_CONFORMANCE_LEVEL = "rdap_level_0";
|
||||||
private static final String VCARD_VERSION_NUMBER = "4.0";
|
private static final String VCARD_VERSION_NUMBER = "4.0";
|
||||||
|
static final String NOTICES = "notices";
|
||||||
|
private static final String REMARKS = "remarks";
|
||||||
|
|
||||||
/** Status values specified in RFC 7483 10.2.2. */
|
/** Status values specified in RFC 7483 10.2.2. */
|
||||||
private enum RdapStatus {
|
private enum RdapStatus {
|
||||||
|
@ -183,19 +195,45 @@ public class RdapJsonFormatter {
|
||||||
}});
|
}});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes an object returned by one of the other methods, and creates a final JSON object suitable
|
* Adds the required top-level boilerplate. RFC 7483 specifies that the top-level object should
|
||||||
* for conversion and transmission. This involves adding one top-level entry, since RFC 7483
|
* include an entry indicating the conformance level. The ICANN RDAP Profile document (dated 3
|
||||||
* specifies that the top-level object should include an entry indicating the conformance level.
|
* December 2015) mandates several additional entries, in sections 1.4.4, 1.4.10, 1.5.18 and
|
||||||
|
* 1.5.20. Note that this method will only work if there are no object-specific remarks already in
|
||||||
|
* the JSON object being built. If there are, the boilerplate must be merged in.
|
||||||
*
|
*
|
||||||
* @param rdapJson an RDAP JSON object created by one of the other methods
|
* @param builder a builder for a JSON map object
|
||||||
* @return an RDAP JSON object with same info as the input, with additional top-level fields
|
* @param boilerplateType type of boilerplate to be added; the ICANN RDAP Profile document
|
||||||
|
* mandates extra boilerplate for domain objects
|
||||||
|
* @param notices a list of notices to be inserted before the boilerplate notices. If the TOS
|
||||||
|
* notice is in this list, the method avoids adding a second copy.
|
||||||
|
* @param rdapLinkBase the base for link URLs
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeFinalRdapJson(
|
static void addTopLevelEntries(
|
||||||
ImmutableMap<String, Object> rdapJson) {
|
ImmutableMap.Builder<String, Object> builder,
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
BoilerplateType boilerplateType,
|
||||||
builder.putAll(rdapJson);
|
@Nullable Iterable<ImmutableMap<String, Object>> notices,
|
||||||
|
String rdapLinkBase) {
|
||||||
builder.put("rdapConformance", CONFORMANCE_LIST);
|
builder.put("rdapConformance", CONFORMANCE_LIST);
|
||||||
return builder.build();
|
ImmutableList.Builder<ImmutableMap<String, Object>> noticesBuilder = ImmutableList.builder();
|
||||||
|
ImmutableMap<String, Object> tosNotice =
|
||||||
|
RdapHelpAction.getJsonHelpNotice(RdapHelpAction.TERMS_OF_SERVICE_PATH, rdapLinkBase);
|
||||||
|
boolean tosNoticeFound = false;
|
||||||
|
if (notices != null) {
|
||||||
|
noticesBuilder.addAll(notices);
|
||||||
|
for (ImmutableMap<String, Object> notice : notices) {
|
||||||
|
if (notice.equals(tosNotice)) {
|
||||||
|
tosNoticeFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tosNoticeFound) {
|
||||||
|
noticesBuilder.add(tosNotice);
|
||||||
|
}
|
||||||
|
builder.put(NOTICES, noticesBuilder.build());
|
||||||
|
builder.put(REMARKS, (boilerplateType == BoilerplateType.DOMAIN)
|
||||||
|
? RdapIcannStandardInformation.domainBoilerplateRemarks
|
||||||
|
: RdapIcannStandardInformation.nonDomainBoilerplateRemarks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** AutoValue class to build parameters to {@link #makeRdapJsonNotice}. */
|
/** AutoValue class to build parameters to {@link #makeRdapJsonNotice}. */
|
||||||
|
@ -225,7 +263,7 @@ public class RdapJsonFormatter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a JSON object containing a notice or remark object, as defined by RFC 7483 section 4.3.
|
* Creates a JSON object containing a notice or remark object, as defined by RFC 7483 section 4.3.
|
||||||
* The object should then be inserted into a "notices" or "remarks" array. The builder fields are:
|
* The object should then be inserted into a notices or remarks array. The builder fields are:
|
||||||
*
|
*
|
||||||
* <p>title: the title of the notice; if null, the notice will have no title
|
* <p>title: the title of the notice; if null, the notice will have no title
|
||||||
*
|
*
|
||||||
|
@ -251,8 +289,8 @@ public class RdapJsonFormatter {
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc7483">
|
* @see <a href="https://tools.ietf.org/html/rfc7483">
|
||||||
* RFC 7483: JSON Responses for the Registration Data Access Protocol (RDAP)</a>
|
* RFC 7483: JSON Responses for the Registration Data Access Protocol (RDAP)</a>
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object>
|
static ImmutableMap<String, Object> makeRdapJsonNotice(
|
||||||
makeRdapJsonNotice(MakeRdapJsonNoticeParameters parameters, @Nullable String linkBase) {
|
MakeRdapJsonNoticeParameters parameters, @Nullable String linkBase) {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
if (parameters.title() != null) {
|
if (parameters.title() != null) {
|
||||||
builder.put("title", parameters.title());
|
builder.put("title", parameters.title());
|
||||||
|
@ -293,8 +331,11 @@ public class RdapJsonFormatter {
|
||||||
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
||||||
* port43 field; if null, port43 is not added to the object
|
* port43 field; if null, port43 is not added to the object
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeRdapJsonForDomain(
|
static ImmutableMap<String, Object> makeRdapJsonForDomain(
|
||||||
DomainResource domainResource, @Nullable String linkBase, @Nullable String whoisServer) {
|
DomainResource domainResource,
|
||||||
|
boolean isTopLevel,
|
||||||
|
@Nullable String linkBase,
|
||||||
|
@Nullable String whoisServer) {
|
||||||
// Kick off the database loads of the nameservers that we will need.
|
// Kick off the database loads of the nameservers that we will need.
|
||||||
Set<Ref<HostResource>> hostRefs = new LinkedHashSet<>();
|
Set<Ref<HostResource>> hostRefs = new LinkedHashSet<>();
|
||||||
for (ReferenceUnion<HostResource> hostReference : domainResource.getNameservers()) {
|
for (ReferenceUnion<HostResource> hostReference : domainResource.getNameservers()) {
|
||||||
|
@ -328,7 +369,7 @@ public class RdapJsonFormatter {
|
||||||
ImmutableList.Builder<Object> nsBuilder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<Object> nsBuilder = new ImmutableList.Builder<>();
|
||||||
for (HostResource hostResource
|
for (HostResource hostResource
|
||||||
: HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
|
: HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
|
||||||
nsBuilder.add(makeRdapJsonForHost(hostResource, linkBase, null));
|
nsBuilder.add(makeRdapJsonForHost(hostResource, false, linkBase, null));
|
||||||
}
|
}
|
||||||
ImmutableList<Object> ns = nsBuilder.build();
|
ImmutableList<Object> ns = nsBuilder.build();
|
||||||
if (!ns.isEmpty()) {
|
if (!ns.isEmpty()) {
|
||||||
|
@ -341,7 +382,7 @@ public class RdapJsonFormatter {
|
||||||
ContactResource loadedContact =
|
ContactResource loadedContact =
|
||||||
loadedContacts.get(designatedContact.getContactId().getLinked().key());
|
loadedContacts.get(designatedContact.getContactId().getLinked().key());
|
||||||
entitiesBuilder.add(makeRdapJsonForContact(
|
entitiesBuilder.add(makeRdapJsonForContact(
|
||||||
loadedContact, Optional.of(designatedContact.getType()), linkBase, null));
|
loadedContact, false, Optional.of(designatedContact.getType()), linkBase, null));
|
||||||
}
|
}
|
||||||
ImmutableList<Object> entities = entitiesBuilder.build();
|
ImmutableList<Object> entities = entitiesBuilder.build();
|
||||||
if (!entities.isEmpty()) {
|
if (!entities.isEmpty()) {
|
||||||
|
@ -350,6 +391,9 @@ public class RdapJsonFormatter {
|
||||||
if (whoisServer != null) {
|
if (whoisServer != null) {
|
||||||
builder.put("port43", whoisServer);
|
builder.put("port43", whoisServer);
|
||||||
}
|
}
|
||||||
|
if (isTopLevel) {
|
||||||
|
addTopLevelEntries(builder, BoilerplateType.DOMAIN, null, linkBase);
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,8 +405,11 @@ public class RdapJsonFormatter {
|
||||||
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
||||||
* port43 field; if null, port43 is not added to the object
|
* port43 field; if null, port43 is not added to the object
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeRdapJsonForHost(
|
static ImmutableMap<String, Object> makeRdapJsonForHost(
|
||||||
HostResource hostResource, @Nullable String linkBase, @Nullable String whoisServer) {
|
HostResource hostResource,
|
||||||
|
boolean isTopLevel,
|
||||||
|
@Nullable String linkBase,
|
||||||
|
@Nullable String whoisServer) {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("objectClassName", "nameserver");
|
builder.put("objectClassName", "nameserver");
|
||||||
builder.put("handle", hostResource.getRepoId());
|
builder.put("handle", hostResource.getRepoId());
|
||||||
|
@ -403,6 +450,9 @@ public class RdapJsonFormatter {
|
||||||
if (whoisServer != null) {
|
if (whoisServer != null) {
|
||||||
builder.put("port43", whoisServer);
|
builder.put("port43", whoisServer);
|
||||||
}
|
}
|
||||||
|
if (isTopLevel) {
|
||||||
|
addTopLevelEntries(builder, BoilerplateType.OTHER, null, linkBase);
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,8 +465,9 @@ public class RdapJsonFormatter {
|
||||||
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
||||||
* port43 field; if null, port43 is not added to the object
|
* port43 field; if null, port43 is not added to the object
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeRdapJsonForContact(
|
static ImmutableMap<String, Object> makeRdapJsonForContact(
|
||||||
ContactResource contactResource,
|
ContactResource contactResource,
|
||||||
|
boolean isTopLevel,
|
||||||
Optional<DesignatedContact.Type> contactType,
|
Optional<DesignatedContact.Type> contactType,
|
||||||
@Nullable String linkBase,
|
@Nullable String linkBase,
|
||||||
@Nullable String whoisServer) {
|
@Nullable String whoisServer) {
|
||||||
|
@ -464,6 +515,9 @@ public class RdapJsonFormatter {
|
||||||
if (whoisServer != null) {
|
if (whoisServer != null) {
|
||||||
builder.put("port43", whoisServer);
|
builder.put("port43", whoisServer);
|
||||||
}
|
}
|
||||||
|
if (isTopLevel) {
|
||||||
|
addTopLevelEntries(builder, BoilerplateType.OTHER, null, linkBase);
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,8 +529,11 @@ public class RdapJsonFormatter {
|
||||||
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
||||||
* port43 field; if null, port43 is not added to the object
|
* port43 field; if null, port43 is not added to the object
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeRdapJsonForRegistrar(
|
static ImmutableMap<String, Object> makeRdapJsonForRegistrar(
|
||||||
Registrar registrar, @Nullable String linkBase, @Nullable String whoisServer) {
|
Registrar registrar,
|
||||||
|
boolean isTopLevel,
|
||||||
|
@Nullable String linkBase,
|
||||||
|
@Nullable String whoisServer) {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("objectClassName", "entity");
|
builder.put("objectClassName", "entity");
|
||||||
builder.put("handle", registrar.getClientIdentifier());
|
builder.put("handle", registrar.getClientIdentifier());
|
||||||
|
@ -534,6 +591,9 @@ public class RdapJsonFormatter {
|
||||||
if (whoisServer != null) {
|
if (whoisServer != null) {
|
||||||
builder.put("port43", whoisServer);
|
builder.put("port43", whoisServer);
|
||||||
}
|
}
|
||||||
|
if (isTopLevel) {
|
||||||
|
addTopLevelEntries(builder, BoilerplateType.OTHER, null, linkBase);
|
||||||
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +604,7 @@ public class RdapJsonFormatter {
|
||||||
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
* @param whoisServer the fully-qualified domain name of the WHOIS server to be listed in the
|
||||||
* port43 field; if null, port43 is not added to the object
|
* port43 field; if null, port43 is not added to the object
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeRdapJsonForRegistrarContact(
|
static ImmutableMap<String, Object> makeRdapJsonForRegistrarContact(
|
||||||
RegistrarContact registrarContact, @Nullable String whoisServer) {
|
RegistrarContact registrarContact, @Nullable String whoisServer) {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("objectClassName", "entity");
|
builder.put("objectClassName", "entity");
|
||||||
|
@ -705,7 +765,7 @@ public class RdapJsonFormatter {
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc7483">
|
* @see <a href="https://tools.ietf.org/html/rfc7483">
|
||||||
* RFC 7483: JSON Responses for the Registration Data Access Protocol (RDAP)</a>
|
* RFC 7483: JSON Responses for the Registration Data Access Protocol (RDAP)</a>
|
||||||
*/
|
*/
|
||||||
public static ImmutableMap<String, Object> makeError(
|
static ImmutableMap<String, Object> makeError(
|
||||||
int status, String title, String description) {
|
int status, String title, String description) {
|
||||||
return ImmutableMap.<String, Object>of(
|
return ImmutableMap.<String, Object>of(
|
||||||
"rdapConformance", CONFORMANCE_LIST,
|
"rdapConformance", CONFORMANCE_LIST,
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class RdapNameserverAction extends RdapActionBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
String pathSearchString) throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
pathSearchString = canonicalizeName(pathSearchString);
|
pathSearchString = canonicalizeName(pathSearchString);
|
||||||
// The RDAP syntax is /rdap/nameserver/ns1.mydomain.com.
|
// The RDAP syntax is /rdap/nameserver/ns1.mydomain.com.
|
||||||
validateDomainName(pathSearchString);
|
validateDomainName(pathSearchString);
|
||||||
|
@ -59,6 +59,6 @@ public class RdapNameserverAction extends RdapActionBase {
|
||||||
if (hostResource == null) {
|
if (hostResource == null) {
|
||||||
throw new NotFoundException(pathSearchString + " not found");
|
throw new NotFoundException(pathSearchString + " not found");
|
||||||
}
|
}
|
||||||
return RdapJsonFormatter.makeRdapJsonForHost(hostResource, rdapLinkBase, rdapWhoisServer);
|
return RdapJsonFormatter.makeRdapJsonForHost(hostResource, true, rdapLinkBase, rdapWhoisServer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import com.google.common.primitives.Booleans;
|
||||||
import com.google.domain.registry.config.ConfigModule.Config;
|
import com.google.domain.registry.config.ConfigModule.Config;
|
||||||
import com.google.domain.registry.model.domain.DomainResource;
|
import com.google.domain.registry.model.domain.DomainResource;
|
||||||
import com.google.domain.registry.model.host.HostResource;
|
import com.google.domain.registry.model.host.HostResource;
|
||||||
|
import com.google.domain.registry.rdap.RdapJsonFormatter.BoilerplateType;
|
||||||
import com.google.domain.registry.request.Action;
|
import com.google.domain.registry.request.Action;
|
||||||
import com.google.domain.registry.request.HttpException;
|
import com.google.domain.registry.request.HttpException;
|
||||||
import com.google.domain.registry.request.HttpException.BadRequestException;
|
import com.google.domain.registry.request.HttpException.BadRequestException;
|
||||||
|
@ -77,8 +78,8 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
|
|
||||||
/** Parses the parameters and calls the appropriate search function. */
|
/** Parses the parameters and calls the appropriate search function. */
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object>
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
getJsonObjectForResource(final String pathSearchString) throws HttpException {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
DateTime now = clock.nowUtc();
|
DateTime now = clock.nowUtc();
|
||||||
// RDAP syntax example: /rdap/nameservers?name=ns*.example.com.
|
// RDAP syntax example: /rdap/nameservers?name=ns*.example.com.
|
||||||
// The pathSearchString is not used by search commands.
|
// The pathSearchString is not used by search commands.
|
||||||
|
@ -105,7 +106,10 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
if (results.isEmpty()) {
|
if (results.isEmpty()) {
|
||||||
throw new NotFoundException("No nameservers found");
|
throw new NotFoundException("No nameservers found");
|
||||||
}
|
}
|
||||||
return ImmutableMap.<String, Object>of("nameserverSearchResults", results);
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
|
builder.put("nameserverSearchResults", results);
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(builder, BoilerplateType.OTHER, null, rdapLinkBase);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Searches for nameservers by name, returning a JSON array of nameserver info maps. */
|
/** Searches for nameservers by name, returning a JSON array of nameserver info maps. */
|
||||||
|
@ -120,7 +124,8 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
throw new NotFoundException("No nameservers found");
|
throw new NotFoundException("No nameservers found");
|
||||||
}
|
}
|
||||||
return ImmutableList.of(
|
return ImmutableList.of(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(hostResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
|
hostResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
// Handle queries with a wildcard, but no suffix. There are no pending deletes for hosts, so we
|
// Handle queries with a wildcard, but no suffix. There are no pending deletes for hosts, so we
|
||||||
// can call queryUndeleted.
|
// can call queryUndeleted.
|
||||||
} else if (partialStringQuery.getSuffix() == null) {
|
} else if (partialStringQuery.getSuffix() == null) {
|
||||||
|
@ -131,7 +136,8 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
ImmutableList.Builder<ImmutableMap<String, Object>> builder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<ImmutableMap<String, Object>> builder = new ImmutableList.Builder<>();
|
||||||
for (HostResource hostResource : query) {
|
for (HostResource hostResource : query) {
|
||||||
builder.add(
|
builder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(hostResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
|
hostResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
// Handle queries with a wildcard and a suffix. In this case, it is more efficient to do things
|
// Handle queries with a wildcard and a suffix. In this case, it is more efficient to do things
|
||||||
|
@ -151,7 +157,8 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
HostResource hostResource = loadByUniqueId(HostResource.class, fqhn, clock.nowUtc());
|
HostResource hostResource = loadByUniqueId(HostResource.class, fqhn, clock.nowUtc());
|
||||||
if (hostResource != null) {
|
if (hostResource != null) {
|
||||||
builder.add(
|
builder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(hostResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
|
hostResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +181,8 @@ public class RdapNameserverSearchAction extends RdapActionBase {
|
||||||
ImmutableList.Builder<ImmutableMap<String, Object>> builder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<ImmutableMap<String, Object>> builder = new ImmutableList.Builder<>();
|
||||||
for (HostResource hostResource : query) {
|
for (HostResource hostResource : query) {
|
||||||
builder.add(
|
builder.add(
|
||||||
RdapJsonFormatter.makeRdapJsonForHost(hostResource, rdapLinkBase, rdapWhoisServer));
|
RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
|
hostResource, false, rdapLinkBase, rdapWhoisServer));
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,12 @@ import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.domain.registry.request.Action.Method.GET;
|
import static com.google.domain.registry.request.Action.Method.GET;
|
||||||
import static com.google.domain.registry.request.Action.Method.HEAD;
|
import static com.google.domain.registry.request.Action.Method.HEAD;
|
||||||
import static com.google.domain.registry.testing.DatastoreHelper.createTld;
|
import static com.google.domain.registry.testing.DatastoreHelper.createTld;
|
||||||
|
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.domain.registry.model.ofy.Ofy;
|
import com.google.domain.registry.model.ofy.Ofy;
|
||||||
|
import com.google.domain.registry.rdap.RdapJsonFormatter.BoilerplateType;
|
||||||
|
import com.google.domain.registry.request.HttpException;
|
||||||
import com.google.domain.registry.testing.AppEngineRule;
|
import com.google.domain.registry.testing.AppEngineRule;
|
||||||
import com.google.domain.registry.testing.FakeClock;
|
import com.google.domain.registry.testing.FakeClock;
|
||||||
import com.google.domain.registry.testing.FakeResponse;
|
import com.google.domain.registry.testing.FakeResponse;
|
||||||
|
@ -68,14 +71,22 @@ public class RdapActionBaseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableMap<String, Object> getJsonObjectForResource(String searchString) {
|
public ImmutableMap<String, Object> getJsonObjectForResource(
|
||||||
if (searchString.equals("IllegalArgumentException")) {
|
String pathSearchString, boolean isHeadRequest, String linkBase) throws HttpException {
|
||||||
|
if (pathSearchString.equals("IllegalArgumentException")) {
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
if (searchString.equals("RuntimeException")) {
|
if (pathSearchString.equals("RuntimeException")) {
|
||||||
throw new RuntimeException();
|
throw new RuntimeException();
|
||||||
}
|
}
|
||||||
return ImmutableMap.<String, Object>of("key", "value");
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
|
builder.put("key", "value");
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
BoilerplateType.OTHER,
|
||||||
|
null,
|
||||||
|
"http://myserver.google.com/");
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +103,7 @@ public class RdapActionBaseTest {
|
||||||
private Object generateActualJson(String domainName) {
|
private Object generateActualJson(String domainName) {
|
||||||
action.requestPath = RdapTestAction.PATH + domainName;
|
action.requestPath = RdapTestAction.PATH + domainName;
|
||||||
action.requestMethod = GET;
|
action.requestMethod = GET;
|
||||||
|
action.rdapLinkBase = "http://myserver.google.com/";
|
||||||
action.run();
|
action.run();
|
||||||
return JSONValue.parse(response.getPayload());
|
return JSONValue.parse(response.getPayload());
|
||||||
}
|
}
|
||||||
|
@ -99,6 +111,7 @@ public class RdapActionBaseTest {
|
||||||
private String generateHeadPayload(String domainName) {
|
private String generateHeadPayload(String domainName) {
|
||||||
action.requestPath = RdapTestAction.PATH + domainName;
|
action.requestPath = RdapTestAction.PATH + domainName;
|
||||||
action.requestMethod = HEAD;
|
action.requestMethod = HEAD;
|
||||||
|
action.rdapLinkBase = "http://myserver.google.com/";
|
||||||
action.run();
|
action.run();
|
||||||
return response.getPayload();
|
return response.getPayload();
|
||||||
}
|
}
|
||||||
|
@ -124,7 +137,7 @@ public class RdapActionBaseTest {
|
||||||
@Test
|
@Test
|
||||||
public void testValidName_works() throws Exception {
|
public void testValidName_works() throws Exception {
|
||||||
assertThat(generateActualJson("no.thing")).isEqualTo(JSONValue.parse(
|
assertThat(generateActualJson("no.thing")).isEqualTo(JSONValue.parse(
|
||||||
"{\"rdapConformance\":[\"rdap_level_0\"], \"key\":\"value\"}"));
|
loadFileWithSubstitutions(this.getClass(), "rdapjson_toplevel.json", null)));
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,12 @@ public class RdapDomainActionTest {
|
||||||
if (!map.containsKey("rdapConformance")) {
|
if (!map.containsKey("rdapConformance")) {
|
||||||
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
||||||
}
|
}
|
||||||
|
if (!map.containsKey("notices")) {
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.com/rdap/");
|
||||||
|
}
|
||||||
|
if (!map.containsKey("remarks")) {
|
||||||
|
RdapTestHelper.addDomainBoilerplateRemarks(builder);
|
||||||
|
}
|
||||||
if (!map.containsKey("port43")) {
|
if (!map.containsKey("port43")) {
|
||||||
builder.put("port43", "whois.example.com");
|
builder.put("port43", "whois.example.com");
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,6 +210,8 @@ public class RdapDomainSearchActionTest {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("domainSearchResults", ImmutableList.of(obj));
|
builder.put("domainSearchResults", ImmutableList.of(obj));
|
||||||
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.com/rdap/");
|
||||||
|
RdapTestHelper.addDomainBoilerplateRemarks(builder);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,12 @@ public class RdapEntityActionTest {
|
||||||
if (!map.containsKey("port43")) {
|
if (!map.containsKey("port43")) {
|
||||||
builder.put("port43", "whois.example.tld");
|
builder.put("port43", "whois.example.tld");
|
||||||
}
|
}
|
||||||
|
if (!map.containsKey("notices")) {
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.com/rdap/");
|
||||||
|
}
|
||||||
|
if (!map.containsKey("remarks")) {
|
||||||
|
RdapTestHelper.addNonDomainBoilerplateRemarks(builder);
|
||||||
|
}
|
||||||
obj = builder.build();
|
obj = builder.build();
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -166,6 +166,8 @@ public class RdapEntitySearchActionTest {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("entitySearchResults", ImmutableList.of(obj));
|
builder.put("entitySearchResults", ImmutableList.of(obj));
|
||||||
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.com/rdap/");
|
||||||
|
RdapTestHelper.addNonDomainBoilerplateRemarks(builder);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,8 @@ public class RdapHelpActionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHelpActionTos_works() throws Exception {
|
public void testHelpActionTos_works() throws Exception {
|
||||||
generateActualJson("/tos");
|
assertThat(generateActualJson("/tos"))
|
||||||
|
.isEqualTo(generateExpectedJson("", "rdap_help_tos.json"));
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,32 +187,36 @@ public class RdapJsonFormatterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegistrar() throws Exception {
|
public void testRegistrar() throws Exception {
|
||||||
assertThat(RdapJsonFormatter.makeRdapJsonForRegistrar(registrar, LINK_BASE, WHOIS_SERVER))
|
assertThat(
|
||||||
.isEqualTo(loadJson("rdapjson_registrar.json"));
|
RdapJsonFormatter.makeRdapJsonForRegistrar(registrar, false, LINK_BASE, WHOIS_SERVER))
|
||||||
|
.isEqualTo(loadJson("rdapjson_registrar.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHost_ipv4() throws Exception {
|
public void testHost_ipv4() throws Exception {
|
||||||
assertThat(RdapJsonFormatter.makeRdapJsonForHost(hostResourceIpv4, LINK_BASE, WHOIS_SERVER))
|
assertThat(
|
||||||
.isEqualTo(loadJson("rdapjson_host_ipv4.json"));
|
RdapJsonFormatter.makeRdapJsonForHost(hostResourceIpv4, false, LINK_BASE, WHOIS_SERVER))
|
||||||
|
.isEqualTo(loadJson("rdapjson_host_ipv4.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHost_ipv6() throws Exception {
|
public void testHost_ipv6() throws Exception {
|
||||||
assertThat(RdapJsonFormatter.makeRdapJsonForHost(hostResourceIpv6, LINK_BASE, WHOIS_SERVER))
|
assertThat(
|
||||||
.isEqualTo(loadJson("rdapjson_host_ipv6.json"));
|
RdapJsonFormatter.makeRdapJsonForHost(hostResourceIpv6, false, LINK_BASE, WHOIS_SERVER))
|
||||||
|
.isEqualTo(loadJson("rdapjson_host_ipv6.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHost_both() throws Exception {
|
public void testHost_both() throws Exception {
|
||||||
assertThat(RdapJsonFormatter.makeRdapJsonForHost(hostResourceBoth, LINK_BASE, WHOIS_SERVER))
|
assertThat(
|
||||||
.isEqualTo(loadJson("rdapjson_host_both.json"));
|
RdapJsonFormatter.makeRdapJsonForHost(hostResourceBoth, false, LINK_BASE, WHOIS_SERVER))
|
||||||
|
.isEqualTo(loadJson("rdapjson_host_both.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHost_noAddresses() throws Exception {
|
public void testHost_noAddresses() throws Exception {
|
||||||
assertThat(RdapJsonFormatter.makeRdapJsonForHost(
|
assertThat(RdapJsonFormatter.makeRdapJsonForHost(
|
||||||
hostResourceNoAddresses, LINK_BASE, WHOIS_SERVER))
|
hostResourceNoAddresses, false, LINK_BASE, WHOIS_SERVER))
|
||||||
.isEqualTo(loadJson("rdapjson_host_no_addresses.json"));
|
.isEqualTo(loadJson("rdapjson_host_no_addresses.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +225,7 @@ public class RdapJsonFormatterTest {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForContact(
|
RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResourceRegistrant,
|
contactResourceRegistrant,
|
||||||
|
false,
|
||||||
Optional.of(DesignatedContact.Type.REGISTRANT),
|
Optional.of(DesignatedContact.Type.REGISTRANT),
|
||||||
LINK_BASE,
|
LINK_BASE,
|
||||||
WHOIS_SERVER))
|
WHOIS_SERVER))
|
||||||
|
@ -232,6 +237,7 @@ public class RdapJsonFormatterTest {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForContact(
|
RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResourceRegistrant,
|
contactResourceRegistrant,
|
||||||
|
false,
|
||||||
Optional.of(DesignatedContact.Type.REGISTRANT),
|
Optional.of(DesignatedContact.Type.REGISTRANT),
|
||||||
LINK_BASE_NO_TRAILING_SLASH,
|
LINK_BASE_NO_TRAILING_SLASH,
|
||||||
WHOIS_SERVER))
|
WHOIS_SERVER))
|
||||||
|
@ -243,6 +249,7 @@ public class RdapJsonFormatterTest {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForContact(
|
RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResourceRegistrant,
|
contactResourceRegistrant,
|
||||||
|
false,
|
||||||
Optional.of(DesignatedContact.Type.REGISTRANT),
|
Optional.of(DesignatedContact.Type.REGISTRANT),
|
||||||
null,
|
null,
|
||||||
WHOIS_SERVER))
|
WHOIS_SERVER))
|
||||||
|
@ -254,6 +261,7 @@ public class RdapJsonFormatterTest {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForContact(
|
RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResourceAdmin,
|
contactResourceAdmin,
|
||||||
|
false,
|
||||||
Optional.of(DesignatedContact.Type.ADMIN),
|
Optional.of(DesignatedContact.Type.ADMIN),
|
||||||
LINK_BASE,
|
LINK_BASE,
|
||||||
WHOIS_SERVER))
|
WHOIS_SERVER))
|
||||||
|
@ -265,6 +273,7 @@ public class RdapJsonFormatterTest {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForContact(
|
RdapJsonFormatter.makeRdapJsonForContact(
|
||||||
contactResourceTech,
|
contactResourceTech,
|
||||||
|
false,
|
||||||
Optional.of(DesignatedContact.Type.TECH),
|
Optional.of(DesignatedContact.Type.TECH),
|
||||||
LINK_BASE,
|
LINK_BASE,
|
||||||
WHOIS_SERVER))
|
WHOIS_SERVER))
|
||||||
|
@ -274,7 +283,8 @@ public class RdapJsonFormatterTest {
|
||||||
@Test
|
@Test
|
||||||
public void testDomain_full() throws Exception {
|
public void testDomain_full() throws Exception {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(domainResourceFull, LINK_BASE, WHOIS_SERVER))
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
|
domainResourceFull, false, LINK_BASE, WHOIS_SERVER))
|
||||||
.isEqualTo(loadJson("rdapjson_domain_full.json"));
|
.isEqualTo(loadJson("rdapjson_domain_full.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +292,7 @@ public class RdapJsonFormatterTest {
|
||||||
public void testDomain_noRegistrant() throws Exception {
|
public void testDomain_noRegistrant() throws Exception {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
domainResourceNoRegistrant, LINK_BASE, WHOIS_SERVER))
|
domainResourceNoRegistrant, false, LINK_BASE, WHOIS_SERVER))
|
||||||
.isEqualTo(loadJson("rdapjson_domain_no_registrant.json"));
|
.isEqualTo(loadJson("rdapjson_domain_no_registrant.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +300,7 @@ public class RdapJsonFormatterTest {
|
||||||
public void testDomain_noContacts() throws Exception {
|
public void testDomain_noContacts() throws Exception {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
domainResourceNoContacts, LINK_BASE, WHOIS_SERVER))
|
domainResourceNoContacts, false, LINK_BASE, WHOIS_SERVER))
|
||||||
.isEqualTo(loadJson("rdapjson_domain_no_contacts.json"));
|
.isEqualTo(loadJson("rdapjson_domain_no_contacts.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +308,7 @@ public class RdapJsonFormatterTest {
|
||||||
public void testDomain_noNameservers() throws Exception {
|
public void testDomain_noNameservers() throws Exception {
|
||||||
assertThat(
|
assertThat(
|
||||||
RdapJsonFormatter.makeRdapJsonForDomain(
|
RdapJsonFormatter.makeRdapJsonForDomain(
|
||||||
domainResourceNoNameservers, LINK_BASE, WHOIS_SERVER))
|
domainResourceNoNameservers, false, LINK_BASE, WHOIS_SERVER))
|
||||||
.isEqualTo(loadJson("rdapjson_domain_no_nameservers.json"));
|
.isEqualTo(loadJson("rdapjson_domain_no_nameservers.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,8 +385,49 @@ public class RdapJsonFormatterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTopLevel() throws Exception {
|
public void testTopLevel() throws Exception {
|
||||||
assertThat(
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
RdapJsonFormatter.makeFinalRdapJson(ImmutableMap.<String, Object>of("key", "value")))
|
builder.put("key", "value");
|
||||||
.isEqualTo(loadJson("rdapjson_toplevel.json"));
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
RdapJsonFormatter.BoilerplateType.OTHER,
|
||||||
|
null,
|
||||||
|
LINK_BASE);
|
||||||
|
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTopLevel_withTermsOfService() throws Exception {
|
||||||
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
|
builder.put("key", "value");
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
RdapJsonFormatter.BoilerplateType.OTHER,
|
||||||
|
ImmutableList.of(RdapHelpAction.getJsonHelpNotice("/tos", LINK_BASE)),
|
||||||
|
LINK_BASE);
|
||||||
|
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTopLevel_domain() throws Exception {
|
||||||
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
|
builder.put("key", "value");
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
RdapJsonFormatter.BoilerplateType.DOMAIN,
|
||||||
|
null,
|
||||||
|
LINK_BASE);
|
||||||
|
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel_domain.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTopLevel_domainWithTermsOfService() throws Exception {
|
||||||
|
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||||
|
builder.put("key", "value");
|
||||||
|
RdapJsonFormatter.addTopLevelEntries(
|
||||||
|
builder,
|
||||||
|
RdapJsonFormatter.BoilerplateType.DOMAIN,
|
||||||
|
ImmutableList.of(RdapHelpAction.getJsonHelpNotice("/tos", LINK_BASE)),
|
||||||
|
LINK_BASE);
|
||||||
|
assertThat(builder.build()).isEqualTo(loadJson("rdapjson_toplevel_domain.json"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,12 @@ public class RdapNameserverActionTest {
|
||||||
if (!map.containsKey("port43")) {
|
if (!map.containsKey("port43")) {
|
||||||
builder.put("port43", "whois.example.tld");
|
builder.put("port43", "whois.example.tld");
|
||||||
}
|
}
|
||||||
|
if (!map.containsKey("notices")) {
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.tld/rdap/");
|
||||||
|
}
|
||||||
|
if (!map.containsKey("remarks")) {
|
||||||
|
RdapTestHelper.addNonDomainBoilerplateRemarks(builder);
|
||||||
|
}
|
||||||
obj = builder.build();
|
obj = builder.build();
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
@ -177,6 +177,8 @@ public class RdapNameserverSearchActionTest {
|
||||||
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
|
||||||
builder.put("nameserverSearchResults", ImmutableList.of(obj));
|
builder.put("nameserverSearchResults", ImmutableList.of(obj));
|
||||||
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
|
||||||
|
RdapTestHelper.addTermsOfServiceNotice(builder, "https://example.tld/rdap/");
|
||||||
|
RdapTestHelper.addNonDomainBoilerplateRemarks(builder);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
javatests/com/google/domain/registry/rdap/RdapTestHelper.java
Normal file
103
javatests/com/google/domain/registry/rdap/RdapTestHelper.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright 2016 Google Inc. 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 com.google.domain.registry.rdap;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
public class RdapTestHelper {
|
||||||
|
|
||||||
|
static void addTermsOfServiceNotice(
|
||||||
|
ImmutableMap.Builder<String, Object> builder, String linkBase) {
|
||||||
|
builder.put("notices",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"title", "RDAP Terms of Service",
|
||||||
|
"description", ImmutableList.of(
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms"
|
||||||
|
+ " so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for"
|
||||||
|
+ " query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the"
|
||||||
|
+ " transmission of mass unsolicited, commercial advertising or"
|
||||||
|
+ " solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated"
|
||||||
|
+ " electronic processes that send queries or data to the systems of"
|
||||||
|
+ " Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful"
|
||||||
|
+ " purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information"
|
||||||
|
+ " contained in the Domain Database in its entirety, or in any substantial"
|
||||||
|
+ " portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the"
|
||||||
|
+ " purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we"
|
||||||
|
+ " suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."),
|
||||||
|
"links", ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"value", linkBase + "help/tos",
|
||||||
|
"rel", "alternate",
|
||||||
|
"href", "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type", "text/html")))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addNonDomainBoilerplateRemarks(ImmutableMap.Builder<String, Object> builder) {
|
||||||
|
builder.put("remarks",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and"
|
||||||
|
+ " Registrars version 1.0"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addDomainBoilerplateRemarks(ImmutableMap.Builder<String, Object> builder) {
|
||||||
|
builder.put("remarks",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and"
|
||||||
|
+ " Registrars version 1.0")),
|
||||||
|
ImmutableMap.of(
|
||||||
|
"title",
|
||||||
|
"EPP Status Codes",
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"For more information on domain status codes, please visit"
|
||||||
|
+ " https://icann.org/epp"),
|
||||||
|
"links",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"value", "https://icann.org/epp",
|
||||||
|
"rel", "alternate",
|
||||||
|
"href", "https://icann.org/epp",
|
||||||
|
"type", "text/html"))),
|
||||||
|
ImmutableMap.of(
|
||||||
|
"description",
|
||||||
|
ImmutableList.of(
|
||||||
|
"URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf"),
|
||||||
|
"links",
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableMap.of(
|
||||||
|
"value", "https://www.icann.org/wicf",
|
||||||
|
"rel", "alternate",
|
||||||
|
"href", "https://www.icann.org/wicf",
|
||||||
|
"type", "text/html")))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,40 @@
|
||||||
"href" : "https://www.registry.google/about/rdap/index.html"
|
"href" : "https://www.registry.google/about/rdap/index.html"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
40
javatests/com/google/domain/registry/rdap/testdata/rdap_help_tos.json
vendored
Normal file
40
javatests/com/google/domain/registry/rdap/testdata/rdap_help_tos.json
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"rdapConformance" : ["rdap_level_0"],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -120,5 +120,42 @@
|
||||||
"port43": "whois.example.tld"
|
"port43": "whois.example.tld"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rdapConformance": [ "rdap_level_0" ]
|
"rdapConformance": [ "rdap_level_0" ],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.com/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,5 +621,73 @@
|
||||||
],
|
],
|
||||||
"rdapConformance": [
|
"rdapConformance": [
|
||||||
"rdap_level_0"
|
"rdap_level_0"
|
||||||
|
],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.com/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title" : "EPP Status Codes",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"For more information on domain status codes, please visit https://icann.org/epp"
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://icann.org/epp",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://icann.org/epp",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf"
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://www.icann.org/wicf",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.icann.org/wicf",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,5 +43,42 @@
|
||||||
"port43": "whois.example.tld"
|
"port43": "whois.example.tld"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rdapConformance" : ["rdap_level_0"]
|
"rdapConformance" : ["rdap_level_0"],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://example.tld/rdap/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,42 @@
|
||||||
"rdapConformance" :
|
"rdapConformance" :
|
||||||
[
|
[
|
||||||
"rdap_level_0"
|
"rdap_level_0"
|
||||||
|
],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "http://myserver.google.com/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
75
javatests/com/google/domain/registry/rdap/testdata/rdapjson_toplevel_domain.json
vendored
Normal file
75
javatests/com/google/domain/registry/rdap/testdata/rdapjson_toplevel_domain.json
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
{
|
||||||
|
"key" : "value",
|
||||||
|
"rdapConformance" :
|
||||||
|
[
|
||||||
|
"rdap_level_0"
|
||||||
|
],
|
||||||
|
"notices" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title" : "RDAP Terms of Service",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"By querying our Domain Database, you are agreeing to comply with these terms so please read them carefully.",
|
||||||
|
"Any information provided is 'as is' without any guarantee of accuracy.",
|
||||||
|
"Please do not misuse the Domain Database. It is intended solely for query-based access.",
|
||||||
|
"Don't use the Domain Database to allow, enable, or otherwise support the transmission of mass unsolicited, commercial advertising or solicitations.",
|
||||||
|
"Don't access our Domain Database through the use of high volume, automated electronic processes that send queries or data to the systems of Charleston Road Registry or any ICANN-accredited registrar.",
|
||||||
|
"You may only use the information contained in the Domain Database for lawful purposes.",
|
||||||
|
"Do not compile, repackage, disseminate, or otherwise use the information contained in the Domain Database in its entirety, or in any substantial portion, without our prior written permission.",
|
||||||
|
"We may retain certain details about queries to our Domain Database for the purposes of detecting and preventing misuse.",
|
||||||
|
"We reserve the right to restrict or deny your access to the database if we suspect that you have failed to comply with these terms.",
|
||||||
|
"We reserve the right to modify this agreement at any time."
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "http://myserver.google.com/help/tos",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.registry.google/about/rdap/tos.html",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"remarks" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"This response conforms to the RDAP Operational Profile for gTLD Registries and Registrars version 1.0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title" : "EPP Status Codes",
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"For more information on domain status codes, please visit https://icann.org/epp"
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://icann.org/epp",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://icann.org/epp",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description" :
|
||||||
|
[
|
||||||
|
"URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf"
|
||||||
|
],
|
||||||
|
"links" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"value" : "https://www.icann.org/wicf",
|
||||||
|
"rel" : "alternate",
|
||||||
|
"href" : "https://www.icann.org/wicf",
|
||||||
|
"type" : "text/html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue