RDAP: Add event records to responses

RFC 7483 defines a way to attach events (such as registration, renewal, etc.) to domains, nameservers and entities. The ICANN Profile calls out particular events: registration, expiration, last changed and last update. This CL implements all the ICANN-defined events except last update (defined to be the last update time of the database), which doesn't make so much sense in our system.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117546838
This commit is contained in:
mountford 2016-03-18 07:55:12 -07:00 committed by Justine Tunney
parent 2293be4079
commit 68c0f4647f
32 changed files with 1089 additions and 224 deletions

View file

@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.contact.ContactPhoneNumber; import com.google.domain.registry.model.contact.ContactPhoneNumber;
import com.google.domain.registry.model.contact.ContactResource; import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.contact.PostalInfo; import com.google.domain.registry.model.contact.PostalInfo;
@ -41,11 +42,14 @@ import com.google.domain.registry.model.host.HostResource;
import com.google.domain.registry.model.registrar.Registrar; import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarAddress; import com.google.domain.registry.model.registrar.RegistrarAddress;
import com.google.domain.registry.model.registrar.RegistrarContact; import com.google.domain.registry.model.registrar.RegistrarContact;
import com.google.domain.registry.model.reporting.HistoryEntry;
import com.google.domain.registry.util.Idn; import com.google.domain.registry.util.Idn;
import com.googlecode.objectify.Key; import com.googlecode.objectify.Key;
import com.googlecode.objectify.Ref; import com.googlecode.objectify.Ref;
import org.joda.time.DateTime;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
@ -87,7 +91,7 @@ public class RdapJsonFormatter {
static final String NOTICES = "notices"; static final String NOTICES = "notices";
private static final String REMARKS = "remarks"; 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 {
VALIDATED("validated"), VALIDATED("validated"),
RENEW_PROHIBITED("renew prohibited"), RENEW_PROHIBITED("renew prohibited"),
@ -144,7 +148,7 @@ public class RdapJsonFormatter {
.put(StatusValue.SERVER_UPDATE_PROHIBITED, RdapStatus.UPDATE_PROHIBITED) .put(StatusValue.SERVER_UPDATE_PROHIBITED, RdapStatus.UPDATE_PROHIBITED)
.build()); .build());
/** Role values specified in RFC 7483 10.2.4. */ /** Role values specified in RFC 7483 § 10.2.4. */
private enum RdapEntityRole { private enum RdapEntityRole {
REGISTRANT("registrant"), REGISTRANT("registrant"),
TECH("technical"), TECH("technical"),
@ -166,6 +170,50 @@ public class RdapJsonFormatter {
} }
} }
/** Status values specified in RFC 7483 § 10.2.2. */
private enum RdapEventAction {
REGISTRATION("registration"),
REREGISTRATION("reregistration"),
LAST_CHANGED("last changed"),
EXPIRATION("expiration"),
DELETION("deletion"),
REINSTANTIATION("reinstantiation"),
TRANSFER("transfer"),
LOCKED("locked"),
UNLOCKED("unlocked");
/** Value as it appears in RDAP messages. */
private final String rfc7483String;
private RdapEventAction(String rfc7483String) {
this.rfc7483String = rfc7483String;
}
@Override
public String toString() {
return rfc7483String;
}
}
/** Map of EPP status values to the RDAP equivalents. */
private static final ImmutableMap<HistoryEntry.Type, RdapEventAction>
historyEntryTypeToRdapEventActionMap =
Maps.immutableEnumMap(
new ImmutableMap.Builder<HistoryEntry.Type, RdapEventAction>()
.put(HistoryEntry.Type.CONTACT_CREATE, RdapEventAction.REGISTRATION)
.put(HistoryEntry.Type.CONTACT_DELETE, RdapEventAction.DELETION)
.put(HistoryEntry.Type.CONTACT_TRANSFER_APPROVE, RdapEventAction.TRANSFER)
.put(HistoryEntry.Type.DOMAIN_APPLICATION_CREATE, RdapEventAction.REGISTRATION)
.put(HistoryEntry.Type.DOMAIN_APPLICATION_DELETE, RdapEventAction.DELETION)
.put(HistoryEntry.Type.DOMAIN_CREATE, RdapEventAction.REGISTRATION)
.put(HistoryEntry.Type.DOMAIN_DELETE, RdapEventAction.DELETION)
.put(HistoryEntry.Type.DOMAIN_RENEW, RdapEventAction.REREGISTRATION)
.put(HistoryEntry.Type.DOMAIN_RESTORE, RdapEventAction.REINSTANTIATION)
.put(HistoryEntry.Type.DOMAIN_TRANSFER_APPROVE, RdapEventAction.TRANSFER)
.put(HistoryEntry.Type.HOST_CREATE, RdapEventAction.REGISTRATION)
.put(HistoryEntry.Type.HOST_DELETE, RdapEventAction.DELETION)
.build());
private static final ImmutableList<String> CONFORMANCE_LIST = private static final ImmutableList<String> CONFORMANCE_LIST =
ImmutableList.of(RDAP_CONFORMANCE_LEVEL); ImmutableList.of(RDAP_CONFORMANCE_LEVEL);
@ -262,7 +310,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 § 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
@ -270,7 +318,7 @@ public class RdapJsonFormatter {
* <p>description: objects which will be converted to strings to form the description of the * <p>description: objects which will be converted to strings to form the description of the
* notice (this is the only required field; all others are optional) * notice (this is the only required field; all others are optional)
* *
* <p>typeString: the notice or remark type as defined in section 10.2.1; if null, no type * <p>typeString: the notice or remark type as defined in § 10.2.1; if null, no type
* *
* <p>linkValueSuffix: the path at the end of the URL used in the value field of the link, * <p>linkValueSuffix: the path at the end of the URL used in the value field of the link,
* without any initial slash (e.g. a suffix of help/toc equates to a URL of * without any initial slash (e.g. a suffix of help/toc equates to a URL of
@ -365,7 +413,11 @@ public class RdapJsonFormatter {
builder.put("status", makeStatusValueList(domainResource.getStatusValues())); builder.put("status", makeStatusValueList(domainResource.getStatusValues()));
builder.put("links", ImmutableList.of( builder.put("links", ImmutableList.of(
makeLink("domain", domainResource.getFullyQualifiedDomainName(), linkBase))); makeLink("domain", domainResource.getFullyQualifiedDomainName(), linkBase)));
// nameservers ImmutableList<Object> events = makeEvents(domainResource);
if (!events.isEmpty()) {
builder.put("events", events);
}
// Nameservers
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())) {
@ -375,7 +427,7 @@ public class RdapJsonFormatter {
if (!ns.isEmpty()) { if (!ns.isEmpty()) {
builder.put("nameservers", ns); builder.put("nameservers", ns);
} }
// contacts // Contacts
ImmutableList.Builder<Object> entitiesBuilder = new ImmutableList.Builder<>(); ImmutableList.Builder<Object> entitiesBuilder = new ImmutableList.Builder<>();
for (DesignatedContact designatedContact for (DesignatedContact designatedContact
: DESIGNATED_CONTACT_ORDERING.immutableSortedCopy(allContacts)) { : DESIGNATED_CONTACT_ORDERING.immutableSortedCopy(allContacts)) {
@ -421,6 +473,10 @@ public class RdapJsonFormatter {
builder.put("status", makeStatusValueList(hostResource.getStatusValues())); builder.put("status", makeStatusValueList(hostResource.getStatusValues()));
builder.put("links", ImmutableList.of( builder.put("links", ImmutableList.of(
makeLink("nameserver", hostResource.getFullyQualifiedHostName(), linkBase))); makeLink("nameserver", hostResource.getFullyQualifiedHostName(), linkBase)));
ImmutableList<Object> events = makeEvents(hostResource);
if (!events.isEmpty()) {
builder.put("events", events);
}
ImmutableSet<InetAddress> inetAddresses = hostResource.getInetAddresses(); ImmutableSet<InetAddress> inetAddresses = hostResource.getInetAddresses();
if (!inetAddresses.isEmpty()) { if (!inetAddresses.isEmpty()) {
ImmutableList.Builder<String> v4AddressesBuilder = new ImmutableList.Builder<>(); ImmutableList.Builder<String> v4AddressesBuilder = new ImmutableList.Builder<>();
@ -512,6 +568,10 @@ public class RdapJsonFormatter {
vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress)); vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress));
} }
builder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build())); builder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build()));
ImmutableList<Object> events = makeEvents(contactResource);
if (!events.isEmpty()) {
builder.put("events", events);
}
if (whoisServer != null) { if (whoisServer != null) {
builder.put("port43", whoisServer); builder.put("port43", whoisServer);
} }
@ -576,6 +636,10 @@ public class RdapJsonFormatter {
vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress)); vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress));
} }
builder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build())); builder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build()));
ImmutableList<Object> events = makeEvents(registrar);
if (!events.isEmpty()) {
builder.put("events", events);
}
// include the registrar contacts as subentities // include the registrar contacts as subentities
ImmutableList.Builder<Map<String, Object>> registrarContactsBuilder = ImmutableList.Builder<Map<String, Object>> registrarContactsBuilder =
new ImmutableList.Builder<>(); new ImmutableList.Builder<>();
@ -676,6 +740,69 @@ public class RdapJsonFormatter {
|| registrarContact.getVisibleInWhoisAsTech(); || registrarContact.getVisibleInWhoisAsTech();
} }
/**
* Creates an event list for a domain, host or contact resource.
*/
private static ImmutableList<Object> makeEvents(EppResource resource) {
ImmutableList.Builder<Object> eventsBuilder = new ImmutableList.Builder<>();
for (HistoryEntry historyEntry : ofy().load()
.type(HistoryEntry.class)
.ancestor(resource)
.order("modificationTime")) {
// Only create an event if this is a type we care about.
if (!historyEntryTypeToRdapEventActionMap.containsKey(historyEntry.getType())) {
continue;
}
RdapEventAction eventAction =
historyEntryTypeToRdapEventActionMap.get(historyEntry.getType());
eventsBuilder.add(makeEvent(
eventAction, historyEntry.getClientId(), historyEntry.getModificationTime()));
}
if (resource instanceof DomainResource) {
DateTime expirationTime = ((DomainResource) resource).getRegistrationExpirationTime();
if (expirationTime != null) {
eventsBuilder.add(makeEvent(RdapEventAction.EXPIRATION, null, expirationTime));
}
}
if ((resource.getLastEppUpdateTime() != null)
&& resource.getLastEppUpdateTime().isAfter(resource.getCreationTime())) {
eventsBuilder.add(makeEvent(
RdapEventAction.LAST_CHANGED, null, resource.getLastEppUpdateTime()));
}
return eventsBuilder.build();
}
/**
* Creates an event list for a {@link Registrar}.
*/
private static ImmutableList<Object> makeEvents(Registrar registrar) {
ImmutableList.Builder<Object> eventsBuilder = new ImmutableList.Builder<>();
eventsBuilder.add(makeEvent(
RdapEventAction.REGISTRATION,
registrar.getClientIdentifier(),
registrar.getCreationTime()));
if ((registrar.getLastUpdateTime() != null)
&& registrar.getLastUpdateTime().isAfter(registrar.getCreationTime())) {
eventsBuilder.add(makeEvent(
RdapEventAction.LAST_CHANGED, null, registrar.getLastUpdateTime()));
}
return eventsBuilder.build();
}
/**
* Creates an RDAP event object as defined by RFC 7483.
*/
private static ImmutableMap<String, Object> makeEvent(
RdapEventAction eventAction, @Nullable String eventActor, DateTime eventDate) {
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("eventAction", eventAction.toString());
if (eventActor != null) {
builder.put("eventActor", eventActor);
}
builder.put("eventDate", eventDate.toString());
return builder.build();
}
/** /**
* Creates a vCard address entry: array of strings specifying the components of the address. * Creates a vCard address entry: array of strings specifying the components of the address.
* *

View file

@ -18,9 +18,10 @@ import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
@ -28,10 +29,13 @@ import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubs
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.model.contact.ContactResource; import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.domain.DomainBase;
import com.google.domain.registry.model.domain.Period;
import com.google.domain.registry.model.host.HostResource; import com.google.domain.registry.model.host.HostResource;
import com.google.domain.registry.model.ofy.Ofy; import com.google.domain.registry.model.ofy.Ofy;
import com.google.domain.registry.model.registrar.Registrar; import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registry.Registry; import com.google.domain.registry.model.registry.Registry;
import com.google.domain.registry.model.reporting.HistoryEntry;
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;
@ -73,25 +77,22 @@ public class RdapDomainActionTest {
Registrar registrarLol = persistResource(makeRegistrar( Registrar registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE)); "evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrarLol)); persistSimpleGlobalResources(makeRegistrarContacts(registrarLol));
ContactResource registrant = ContactResource registrant = makeAndPersistContactResource(
persistResource(makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")); "5372808-ERL", "Goblin Market", "lol@cat.lol", clock.nowUtc().minusYears(1));
ContactResource adminContact = ContactResource adminContact = makeAndPersistContactResource(
persistResource(makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol")); "5372808-IRL", "Santa Claus", "BOFH@cat.lol", clock.nowUtc().minusYears(2));
ContactResource techContact = ContactResource techContact = makeAndPersistContactResource(
persistResource(makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol")); "5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3));
HostResource host1 = HostResource host1 = makeAndPersistHostResource(
persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4")); "ns1.cat.lol", "1.2.3.4", clock.nowUtc().minusYears(1));
HostResource host2 = HostResource host2 = makeAndPersistHostResource(
persistResource(makeHostResource("ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef")); "ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
persistResource(makeDomainResource("cat.lol", DomainBase domainCatLol =
registrant, persistResource(makeDomainResource("cat.lol",
adminContact, registrant, adminContact, techContact, host1, host2, registrarLol));
techContact,
host1,
host2,
registrarLol));
// deleted domain in lol // deleted domain in lol
persistResource(makeDomainResource("dodo.lol", DomainBase domainDeleted = persistResource(makeDomainResource("dodo.lol",
registrant, registrant,
adminContact, adminContact,
techContact, techContact,
@ -103,7 +104,7 @@ public class RdapDomainActionTest {
Registrar registrarIdn = Registrar registrarIdn =
persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE)); persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrarIdn)); persistSimpleGlobalResources(makeRegistrarContacts(registrarIdn));
persistResource(makeDomainResource("cat.みんな", DomainBase domainCatIdn = persistResource(makeDomainResource("cat.みんな",
registrant, registrant,
adminContact, adminContact,
techContact, techContact,
@ -114,7 +115,7 @@ public class RdapDomainActionTest {
Registrar registrar1tld = persistResource( Registrar registrar1tld = persistResource(
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE)); makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar1tld)); persistSimpleGlobalResources(makeRegistrarContacts(registrar1tld));
persistResource(makeDomainResource("cat.1.tld", DomainBase domainCat1Tld = persistResource(makeDomainResource("cat.1.tld",
registrant, registrant,
adminContact, adminContact,
techContact, techContact,
@ -126,6 +127,36 @@ public class RdapDomainActionTest {
action.response = response; action.response = response;
action.rdapLinkBase = "https://example.com/rdap/"; action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = "whois.example.tld"; action.rdapWhoisServer = "whois.example.tld";
// history entries
persistResource(
makeHistoryEntry(
domainCatLol,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainDeleted,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainCatIdn,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainCat1Tld,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
} }
private Object generateActualJson(String domainName) { private Object generateActualJson(String domainName) {
@ -203,21 +234,21 @@ public class RdapDomainActionTest {
@Test @Test
public void testValidDomain_works() throws Exception { public void testValidDomain_works() throws Exception {
assertThat(generateActualJson("cat.lol")).isEqualTo( assertThat(generateActualJson("cat.lol")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "7-LOL", "rdap_domain.json")); generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testTrailingDot_ignored() throws Exception { public void testTrailingDot_ignored() throws Exception {
assertThat(generateActualJson("cat.lol.")).isEqualTo( assertThat(generateActualJson("cat.lol.")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "7-LOL", "rdap_domain.json")); generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testQueryParameter_ignored() throws Exception { public void testQueryParameter_ignored() throws Exception {
assertThat(generateActualJson("cat.lol?key=value")).isEqualTo( assertThat(generateActualJson("cat.lol?key=value")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "7-LOL", "rdap_domain.json")); generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -225,7 +256,7 @@ public class RdapDomainActionTest {
public void testIdnDomain_works() throws Exception { public void testIdnDomain_works() throws Exception {
assertThat(generateActualJson("cat.みんな")).isEqualTo( assertThat(generateActualJson("cat.みんな")).isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "A-Q9JYB4C", "rdap_domain_unicode.json")); "cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -233,7 +264,7 @@ public class RdapDomainActionTest {
public void testIdnDomainWithPercentEncoding_works() throws Exception { public void testIdnDomainWithPercentEncoding_works() throws Exception {
assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA")).isEqualTo( assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA")).isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "A-Q9JYB4C", "rdap_domain_unicode.json")); "cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -241,14 +272,14 @@ public class RdapDomainActionTest {
public void testPunycodeDomain_works() throws Exception { public void testPunycodeDomain_works() throws Exception {
assertThat(generateActualJson("cat.xn--q9jyb4c")).isEqualTo( assertThat(generateActualJson("cat.xn--q9jyb4c")).isEqualTo(
generateExpectedJsonWithTopLevelEntries( generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "A-Q9JYB4C", "rdap_domain_unicode.json")); "cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@Test @Test
public void testMultilevelDomain_works() throws Exception { public void testMultilevelDomain_works() throws Exception {
assertThat(generateActualJson("cat.1.tld")).isEqualTo( assertThat(generateActualJson("cat.1.tld")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.1.tld", null, "C-1.TLD", "rdap_domain.json")); generateExpectedJsonWithTopLevelEntries("cat.1.tld", null, "11-1.TLD", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }

View file

@ -19,9 +19,10 @@ import static com.google.domain.registry.testing.DatastoreHelper.createTld;
import static com.google.domain.registry.testing.DatastoreHelper.persistDomainAsDeleted; import static com.google.domain.registry.testing.DatastoreHelper.persistDomainAsDeleted;
import static com.google.domain.registry.testing.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
@ -33,10 +34,12 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.domain.registry.model.domain.DomainResource; import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.Period;
import com.google.domain.registry.model.host.HostResource; import com.google.domain.registry.model.host.HostResource;
import com.google.domain.registry.model.ofy.Ofy; import com.google.domain.registry.model.ofy.Ofy;
import com.google.domain.registry.model.registrar.Registrar; import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registry.Registry; import com.google.domain.registry.model.registry.Registry;
import com.google.domain.registry.model.reporting.HistoryEntry;
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;
@ -66,7 +69,7 @@ public class RdapDomainSearchActionTest {
public final InjectRule inject = new InjectRule(); public final InjectRule inject = new InjectRule();
private final FakeResponse response = new FakeResponse(); private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2009-06-29T20:13:00Z")); private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final RdapDomainSearchAction action = new RdapDomainSearchAction(); private final RdapDomainSearchAction action = new RdapDomainSearchAction();
@ -108,18 +111,38 @@ public class RdapDomainSearchActionTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
inject.setStaticField(Ofy.class, "clock", clock);
// cat.lol and cat2.lol // cat.lol and cat2.lol
createTld("lol"); createTld("lol");
Registrar registrar = persistResource( Registrar registrar = persistResource(
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE)); makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
domainCatLol = persistResource(makeDomainResource("cat.lol", domainCatLol = persistResource(makeDomainResource(
persistResource(makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")), "cat.lol",
persistResource(makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol")), makeAndPersistContactResource(
persistResource(makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol")), "5372808-ERL",
hostNs1CatLol = persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4")), "Goblin Market",
hostNs2CatLol = persistResource( "lol@cat.lol",
makeHostResource("ns2.cat.lol", "bad:f00d:cafe::15:beef")), clock.nowUtc().minusYears(1)),
makeAndPersistContactResource(
"5372808-IRL",
"Santa Claus",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2)),
makeAndPersistContactResource(
"5372808-TRL",
"The Raven",
"bog@cat.lol",
clock.nowUtc().minusYears(3)),
hostNs1CatLol = makeAndPersistHostResource(
"ns1.cat.lol",
"1.2.3.4",
clock.nowUtc().minusYears(1)),
hostNs2CatLol = makeAndPersistHostResource(
"ns2.cat.lol",
"bad:f00d:cafe::15:beef",
clock.nowUtc().minusYears(2)),
registrar) registrar)
.asBuilder().setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol")).build()); .asBuilder().setSubordinateHosts(ImmutableSet.of("ns1.cat.lol", "ns2.cat.lol")).build());
persistResource( persistResource(
@ -128,34 +151,76 @@ public class RdapDomainSearchActionTest {
hostNs2CatLol.asBuilder().setSuperordinateDomain(Ref.create(domainCatLol)).build()); hostNs2CatLol.asBuilder().setSuperordinateDomain(Ref.create(domainCatLol)).build());
domainCatLol2 = persistResource(makeDomainResource( domainCatLol2 = persistResource(makeDomainResource(
"cat2.lol", "cat2.lol",
persistResource(makeContactResource("6372808-ERL", "Siegmund", "siegmund@cat2.lol")), makeAndPersistContactResource(
persistResource(makeContactResource("6372808-IRL", "Sieglinde", "sieglinde@cat2.lol")), "6372808-ERL",
persistResource(makeContactResource("6372808-TRL", "Siegfried", "siegfried@cat2.lol")), "Siegmund",
persistResource(makeHostResource("ns1.cat.example", "10.20.30.40")), "siegmund@cat2.lol",
persistResource(makeHostResource("ns2.dog.lol", "12:feed:5000::15:beef")), clock.nowUtc().minusYears(1)),
makeAndPersistContactResource(
"6372808-IRL",
"Sieglinde",
"sieglinde@cat2.lol",
clock.nowUtc().minusYears(2)),
makeAndPersistContactResource(
"6372808-TRL",
"Siegfried",
"siegfried@cat2.lol",
clock.nowUtc().minusYears(3)),
makeAndPersistHostResource(
"ns1.cat.example", "10.20.30.40", clock.nowUtc().minusYears(1)),
makeAndPersistHostResource(
"ns2.dog.lol", "12:feed:5000::15:beef", clock.nowUtc().minusYears(2)),
registrar)); registrar));
// cat.example // cat.example
createTld("example"); createTld("example");
registrar = persistResource( registrar = persistResource(
makeRegistrar("goodregistrar", "St. John Chrysostom", Registrar.State.ACTIVE)); makeRegistrar("goodregistrar", "St. John Chrysostom", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
domainCatExample = persistResource(makeDomainResource("cat.example", domainCatExample = persistResource(makeDomainResource(
persistResource(makeContactResource("7372808-ERL", "Matthew", "lol@cat.lol")), "cat.example",
persistResource(makeContactResource("7372808-IRL", "Mark", "BOFH@cat.lol")), makeAndPersistContactResource(
persistResource(makeContactResource("7372808-TRL", "Luke", "bog@cat.lol")), "7372808-ERL",
"Matthew",
"lol@cat.lol",
clock.nowUtc().minusYears(1)),
makeAndPersistContactResource(
"7372808-IRL",
"Mark",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2)),
makeAndPersistContactResource(
"7372808-TRL",
"Luke",
"bog@cat.lol",
clock.nowUtc().minusYears(3)),
hostNs1CatLol, hostNs1CatLol,
persistResource(makeHostResource("ns2.external.tld", "bad:f00d:cafe::15:beef")), makeAndPersistHostResource(
"ns2.external.tld", "bad:f00d:cafe::15:beef", clock.nowUtc().minusYears(2)),
registrar)); registrar));
// cat.みんな // cat.みんな
createTld("xn--q9jyb4c"); createTld("xn--q9jyb4c");
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE)); registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
persistResource(makeDomainResource( persistResource(makeDomainResource(
"cat.みんな", persistResource(makeContactResource("8372808-ERL", "(◕‿◕)", "lol@cat.みんな")), "cat.みんな",
persistResource(makeContactResource("8372808-IRL", "Santa Claus", "BOFH@cat.みんな")), makeAndPersistContactResource(
persistResource(makeContactResource("8372808-TRL", "The Raven", "bog@cat.みんな")), "8372808-ERL",
persistResource(makeHostResource("ns1.cat.みんな", "1.2.3.5")), "(◕‿◕)",
persistResource(makeHostResource("ns2.cat.みんな", "bad:f00d:cafe::14:beef")), "lol@cat.みんな",
clock.nowUtc().minusYears(1)),
makeAndPersistContactResource(
"8372808-IRL",
"Santa Claus",
"BOFH@cat.みんな",
clock.nowUtc().minusYears(2)),
makeAndPersistContactResource(
"8372808-TRL",
"The Raven",
"bog@cat.みんな",
clock.nowUtc().minusYears(3)),
makeAndPersistHostResource("ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1)),
makeAndPersistHostResource(
"ns2.cat.みんな", "bad:f00d:cafe::14:beef", clock.nowUtc().minusYears(2)),
registrar)); registrar));
// cat.1.test // cat.1.test
createTld("1.test"); createTld("1.test");
@ -163,16 +228,51 @@ public class RdapDomainSearchActionTest {
persistResource(makeRegistrar("unicoderegistrar", "1.test", Registrar.State.ACTIVE)); persistResource(makeRegistrar("unicoderegistrar", "1.test", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
persistResource(makeDomainResource( persistResource(makeDomainResource(
"cat.1.test", "cat.1.test",
persistResource(makeContactResource("9372808-ERL", "(◕‿◕)", "lol@cat.みんな")), makeAndPersistContactResource(
persistResource(makeContactResource("9372808-IRL", "Santa Claus", "BOFH@cat.みんな")), "9372808-ERL",
persistResource(makeContactResource("9372808-TRL", "The Raven", "bog@cat.みんな")), "(◕‿◕)",
persistResource(makeHostResource("ns1.cat.1.test", "1.2.3.5")), "lol@cat.みんな",
persistResource(makeHostResource("ns2.cat.2.test", "bad:f00d:cafe::14:beef")), clock.nowUtc().minusYears(1)),
registrar) makeAndPersistContactResource(
"9372808-IRL",
"Santa Claus",
"BOFH@cat.みんな",
clock.nowUtc().minusYears(2)),
makeAndPersistContactResource(
"9372808-TRL",
"The Raven",
"bog@cat.みんな",
clock.nowUtc().minusYears(3)),
makeAndPersistHostResource("ns1.cat.1.test", "1.2.3.5", clock.nowUtc().minusYears(1)),
makeAndPersistHostResource(
"ns2.cat.2.test", "bad:f00d:cafe::14:beef", clock.nowUtc().minusYears(2)),
registrar)
.asBuilder().setSubordinateHosts(ImmutableSet.of("ns1.cat.1.test")).build()); .asBuilder().setSubordinateHosts(ImmutableSet.of("ns1.cat.1.test")).build());
inject.setStaticField(Ofy.class, "clock", clock); // history entries
persistResource(
makeHistoryEntry(
domainCatLol,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainCatLol2,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainCatExample,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
action.clock = clock; action.clock = clock;
action.response = response; action.response = response;
action.rdapLinkBase = "https://example.com/rdap/"; action.rdapLinkBase = "https://example.com/rdap/";
@ -264,7 +364,7 @@ public class RdapDomainSearchActionTest {
@Test @Test
public void testDomainMatch_found() throws Exception { public void testDomainMatch_found() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "cat.lol")) assertThat(generateActualJson(RequestType.NAME, "cat.lol"))
.isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "7-LOL", "rdap_domain.json")); .isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -402,7 +502,7 @@ public class RdapDomainSearchActionTest {
@Test @Test
public void testNameserverMatchWithWildcard_found() throws Exception { public void testNameserverMatchWithWildcard_found() throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns2.cat.l*")) assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns2.cat.l*"))
.isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "7-LOL", "rdap_domain.json")); .isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -487,7 +587,7 @@ public class RdapDomainSearchActionTest {
public void testNameserverMatchOneDeletedDomain_foundTheOther() throws Exception { public void testNameserverMatchOneDeletedDomain_foundTheOther() throws Exception {
persistDomainAsDeleted(domainCatExample, clock.nowUtc()); persistDomainAsDeleted(domainCatExample, clock.nowUtc());
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol")) assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "7-LOL", "rdap_domain.json")); .isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -563,7 +663,7 @@ public class RdapDomainSearchActionTest {
public void testAddressMatchOneDeletedDomain_foundTheOther() throws Exception { public void testAddressMatchOneDeletedDomain_foundTheOther() throws Exception {
persistDomainAsDeleted(domainCatExample, clock.nowUtc()); persistDomainAsDeleted(domainCatExample, clock.nowUtc());
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4")) assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "7-LOL", "rdap_domain.json")); .isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }

View file

@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
@ -78,21 +79,24 @@ public class RdapEntityActionTest {
registrarLol = persistResource(makeRegistrar( registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE)); "evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrarLol)); persistSimpleGlobalResources(makeRegistrarContacts(registrarLol));
registrant = persistResource(makeContactResource( registrant = makeAndPersistContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"))); ImmutableList.of("1 Smiley Row", "Suite みんな"),
adminContact = persistResource(makeContactResource( clock.nowUtc());
adminContact = makeAndPersistContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"))); ImmutableList.of("1 Smiley Row", "Suite みんな"),
techContact = persistResource(makeContactResource( clock.nowUtc());
techContact = makeAndPersistContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"))); ImmutableList.of("1 Smiley Row", "Suite みんな"),
clock.nowUtc());
HostResource host1 = HostResource host1 =
persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4")); persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4"));
HostResource host2 = HostResource host2 =
@ -127,13 +131,13 @@ public class RdapEntityActionTest {
host1, host1,
host2, host2,
registrar1tld)); registrar1tld));
disconnectedContact = persistResource(makeContactResource( disconnectedContact = makeAndPersistContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"))); ImmutableList.of("1 Smiley Row", "Suite みんな"),
deletedContact = persistResource( clock.nowUtc());
makeContactResource( deletedContact = persistResource(makeContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",

View file

@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
@ -49,11 +50,10 @@ import javax.annotation.Nullable;
public class RdapEntitySearchActionTest { public class RdapEntitySearchActionTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build(); @Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Rule public final InjectRule inject = new InjectRule(); @Rule public final InjectRule inject = new InjectRule();
private final FakeResponse response = new FakeResponse(); private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2009-06-29T20:13:00Z")); private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final RdapEntitySearchAction action = new RdapEntitySearchAction(); private final RdapEntitySearchAction action = new RdapEntitySearchAction();
@ -76,14 +76,16 @@ public class RdapEntitySearchActionTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
inject.setStaticField(Ofy.class, "clock", clock);
createTld("tld"); createTld("tld");
contact = persistResource( contact = makeAndPersistContactResource(
makeContactResource( "blinky",
"blinky", "Blinky (赤ベイ)",
"Blinky (赤ベイ)", "blinky@b.tld",
"blinky@b.tld", ImmutableList.of("123 Blinky St", "Blinkyland"),
ImmutableList.of("123 Blinky St", "Blinkyland"))); clock.nowUtc());
// deleted // deleted
persistResource( persistResource(
@ -110,7 +112,6 @@ public class RdapEntitySearchActionTest {
.build()); .build());
persistSimpleGlobalResources(makeRegistrarContacts(registrarTest)); persistSimpleGlobalResources(makeRegistrarContacts(registrarTest));
inject.setStaticField(Ofy.class, "clock", clock);
action.clock = clock; action.clock = clock;
action.requestPath = RdapEntitySearchAction.PATH; action.requestPath = RdapEntitySearchAction.PATH;
action.response = response; action.response = response;

View file

@ -18,9 +18,10 @@ import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntry;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
@ -32,13 +33,19 @@ import com.google.common.collect.ImmutableSet;
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.domain.DomainResource; import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.Period;
import com.google.domain.registry.model.host.HostResource; import com.google.domain.registry.model.host.HostResource;
import com.google.domain.registry.model.ofy.Ofy;
import com.google.domain.registry.model.registrar.Registrar; import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarContact; import com.google.domain.registry.model.registrar.RegistrarContact;
import com.google.domain.registry.model.registry.Registry.TldState; import com.google.domain.registry.model.registry.Registry.TldState;
import com.google.domain.registry.model.reporting.HistoryEntry;
import com.google.domain.registry.rdap.RdapJsonFormatter.MakeRdapJsonNoticeParameters; import com.google.domain.registry.rdap.RdapJsonFormatter.MakeRdapJsonNoticeParameters;
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.InjectRule;
import org.joda.time.DateTime;
import org.json.simple.JSONValue; import org.json.simple.JSONValue;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -54,6 +61,9 @@ public class RdapJsonFormatterTest {
public final AppEngineRule appEngine = AppEngineRule.builder() public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore() .withDatastore()
.build(); .build();
@Rule public final InjectRule inject = new InjectRule();
private final FakeClock clock = new FakeClock(DateTime.parse("1999-01-01T00:00:00Z"));
private Registrar registrar; private Registrar registrar;
private DomainResource domainResourceFull; private DomainResource domainResourceFull;
@ -74,33 +84,43 @@ public class RdapJsonFormatterTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
inject.setStaticField(Ofy.class, "clock", clock);
// Create the registrar in 1999, then update it in 2000.
clock.setTo(DateTime.parse("1999-01-01T00:00:00Z"));
createTld("xn--q9jyb4c", TldState.GENERAL_AVAILABILITY); createTld("xn--q9jyb4c", TldState.GENERAL_AVAILABILITY);
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE)); registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
clock.setTo(DateTime.parse("2000-01-01T00:00:00Z"));
registrar = persistResource(registrar);
persistSimpleGlobalResources(makeMoreRegistrarContacts(registrar)); persistSimpleGlobalResources(makeMoreRegistrarContacts(registrar));
contactResourceRegistrant = persistResource(
makeContactResource( contactResourceRegistrant = makeAndPersistContactResource(
"8372808-ERL", "8372808-ERL",
"(◕‿◕)", "(◕‿◕)",
"lol@cat.みんな", "lol@cat.みんな",
null)); null,
contactResourceAdmin = persistResource( clock.nowUtc().minusYears(1));
makeContactResource( contactResourceAdmin = makeAndPersistContactResource(
"8372808-IRL", "8372808-IRL",
"Santa Claus", "Santa Claus",
null, null,
ImmutableList.of("Santa Claus Tower", "41st floor", "Suite みんな"))); ImmutableList.of("Santa Claus Tower", "41st floor", "Suite みんな"),
contactResourceTech = persistResource( clock.nowUtc().minusYears(2));
makeContactResource( contactResourceTech = makeAndPersistContactResource(
"8372808-TRL", "8372808-TRL",
"The Raven", "The Raven",
"bog@cat.みんな", "bog@cat.みんな",
ImmutableList.of("Chamber Door", "upper level"))); ImmutableList.of("Chamber Door", "upper level"),
hostResourceIpv4 = persistResource(makeHostResource("ns1.cat.みんな", "1.2.3.4")); clock.nowUtc().minusYears(3));
hostResourceIpv6 = hostResourceIpv4 = makeAndPersistHostResource(
persistResource(makeHostResource("ns2.cat.みんな", "bad:f00d:cafe:0:0:0:15:beef")); "ns1.cat.みんな", "1.2.3.4", clock.nowUtc().minusYears(1));
hostResourceBoth = hostResourceIpv6 = makeAndPersistHostResource(
persistResource(makeHostResource("ns3.cat.みんな", "1.2.3.4", "bad:f00d:cafe:0:0:0:15:beef")); "ns2.cat.みんな", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
hostResourceNoAddresses = persistResource(makeHostResource("ns4.cat.みんな", null)); hostResourceBoth = makeAndPersistHostResource(
"ns3.cat.みんな", "1.2.3.4", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(3));
hostResourceNoAddresses = makeAndPersistHostResource(
"ns4.cat.みんな", null, clock.nowUtc().minusYears(4));
domainResourceFull = persistResource( domainResourceFull = persistResource(
makeDomainResource( makeDomainResource(
"cat.みんな", "cat.みんな",
@ -137,6 +157,36 @@ public class RdapJsonFormatterTest {
null, null,
null, null,
registrar)); registrar));
// history entries
persistResource(
makeHistoryEntry(
domainResourceFull,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainResourceNoRegistrant,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainResourceNoContacts,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
persistResource(
makeHistoryEntry(
domainResourceNoNameservers,
HistoryEntry.Type.DOMAIN_CREATE,
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
} }
public static ImmutableList<RegistrarContact> makeMoreRegistrarContacts(Registrar registrar) { public static ImmutableList<RegistrarContact> makeMoreRegistrarContacts(Registrar registrar) {

View file

@ -16,8 +16,7 @@ package com.google.domain.registry.rdap;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import com.google.appengine.api.NamespaceManager; import com.google.appengine.api.NamespaceManager;
@ -61,16 +60,16 @@ public class RdapNameserverActionTest {
inject.setStaticField(Ofy.class, "clock", clock); inject.setStaticField(Ofy.class, "clock", clock);
// normal // normal
createTld("lol"); createTld("lol");
persistResource( makeAndPersistHostResource(
makeHostResource("ns1.cat.lol", "1.2.3.4")); "ns1.cat.lol", "1.2.3.4", clock.nowUtc().minusYears(1));
// idn // idn
createTld("xn--q9jyb4c"); createTld("xn--q9jyb4c");
persistResource( makeAndPersistHostResource(
makeHostResource("ns1.cat.xn--q9jyb4c", "bad:f00d:cafe:0:0:0:15:beef")); "ns1.cat.xn--q9jyb4c", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(1));
// multilevel // multilevel
createTld("1.tld"); createTld("1.tld");
persistResource( makeAndPersistHostResource(
makeHostResource("ns1.domain.1.tld", "5.6.7.8")); "ns1.domain.1.tld", "5.6.7.8", clock.nowUtc().minusYears(1));
NamespaceManager.set(null); NamespaceManager.set(null);
} }
@ -191,7 +190,7 @@ public class RdapNameserverActionTest {
"ns1.cat.みんな", "ns1.cat.みんな",
ImmutableMap.of( ImmutableMap.of(
"PUNYCODENAME", "ns1.cat.xn--q9jyb4c", "PUNYCODENAME", "ns1.cat.xn--q9jyb4c",
"HANDLE", "4-ROID", "HANDLE", "5-ROID",
"ADDRESSTYPE", "v6", "ADDRESSTYPE", "v6",
"ADDRESS", "bad:f00d:cafe::15:beef"), "ADDRESS", "bad:f00d:cafe::15:beef"),
"rdap_host_unicode.json")); "rdap_host_unicode.json"));
@ -205,7 +204,7 @@ public class RdapNameserverActionTest {
"ns1.cat.みんな", "ns1.cat.みんな",
ImmutableMap.of( ImmutableMap.of(
"PUNYCODENAME", "ns1.cat.xn--q9jyb4c", "PUNYCODENAME", "ns1.cat.xn--q9jyb4c",
"HANDLE", "4-ROID", "HANDLE", "5-ROID",
"ADDRESSTYPE", "v6", "ADDRESSTYPE", "v6",
"ADDRESS", "bad:f00d:cafe::15:beef"), "ADDRESS", "bad:f00d:cafe::15:beef"),
"rdap_host_unicode.json")); "rdap_host_unicode.json"));
@ -217,7 +216,7 @@ public class RdapNameserverActionTest {
assertThat(generateActualJson("ns1.domain.1.tld")) assertThat(generateActualJson("ns1.domain.1.tld"))
.isEqualTo(generateExpectedJsonWithTopLevelEntries( .isEqualTo(generateExpectedJsonWithTopLevelEntries(
"ns1.domain.1.tld", "ns1.domain.1.tld",
ImmutableMap.of("HANDLE", "6-ROID", "ADDRESSTYPE", "v4", "ADDRESS", "5.6.7.8"), ImmutableMap.of("HANDLE", "8-ROID", "ADDRESSTYPE", "v4", "ADDRESS", "5.6.7.8"),
"rdap_host.json")); "rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }

View file

@ -18,9 +18,9 @@ import static com.google.common.truth.Truth.assertThat;
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.DatastoreHelper.persistResource; import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources; import static com.google.domain.registry.testing.DatastoreHelper.persistSimpleGlobalResources;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeContactResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeDomainResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeHostResource;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts; import static com.google.domain.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static com.google.domain.registry.testing.TestDataHelper.loadFileWithSubstitutions;
@ -58,7 +58,7 @@ public class RdapNameserverSearchActionTest {
@Rule public final InjectRule inject = new InjectRule(); @Rule public final InjectRule inject = new InjectRule();
private final FakeResponse response = new FakeResponse(); private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2009-06-29T20:13:00Z")); private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final RdapNameserverSearchAction action = new RdapNameserverSearchAction(); private final RdapNameserverSearchAction action = new RdapNameserverSearchAction();
@ -86,23 +86,25 @@ public class RdapNameserverSearchActionTest {
persistResource( persistResource(
makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE)); makeRegistrar("evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
hostNs1CatLol = persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4")); hostNs1CatLol = makeAndPersistHostResource(
hostNs2CatLol = persistResource(makeHostResource("ns2.cat.lol", "bad:f00d:cafe::15:beef")); "ns1.cat.lol", "1.2.3.4", clock.nowUtc().minusYears(1));
hostNs1Cat2Lol = hostNs2CatLol = makeAndPersistHostResource(
persistResource(makeHostResource("ns1.cat2.lol", "1.2.3.3", "bad:f00d:cafe::15:beef")); "ns2.cat.lol", "bad:f00d:cafe::15:beef", clock.nowUtc().minusYears(1));
persistResource(makeHostResource("ns1.cat.external", null)); hostNs1Cat2Lol = makeAndPersistHostResource(
"ns1.cat2.lol", "1.2.3.3", "bad:f00d:cafe::15:beef", clock.nowUtc().minusYears(1));
makeAndPersistHostResource("ns1.cat.external", null, null, clock.nowUtc().minusYears(1));
// cat.みんな // cat.みんな
createTld("xn--q9jyb4c"); createTld("xn--q9jyb4c");
registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE)); registrar = persistResource(makeRegistrar("unicoderegistrar", "みんな", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
persistResource(makeHostResource("ns1.cat.みんな", "1.2.3.5")); makeAndPersistHostResource("ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1));
// cat.1.test // cat.1.test
createTld("1.test"); createTld("1.test");
registrar = persistResource(makeRegistrar("multiregistrar", "1.test", Registrar.State.ACTIVE)); registrar = persistResource(makeRegistrar("multiregistrar", "1.test", Registrar.State.ACTIVE));
persistSimpleGlobalResources(makeRegistrarContacts(registrar)); persistSimpleGlobalResources(makeRegistrarContacts(registrar));
persistResource(makeHostResource("ns1.cat.1.test", "1.2.3.6")); makeAndPersistHostResource("ns1.cat.1.test", "1.2.3.6", clock.nowUtc().minusYears(1));
// create a domain so that we can use it as a test nameserver search string suffix // create a domain so that we can use it as a test nameserver search string suffix
DomainResource domainCatLol = DomainResource domainCatLol =
@ -249,7 +251,7 @@ public class RdapNameserverSearchActionTest {
assertThat(generateActualJsonWithName("ns2.cat.lol")) assertThat(generateActualJsonWithName("ns2.cat.lol"))
.isEqualTo( .isEqualTo(
generateExpectedJsonForNameserver( generateExpectedJsonForNameserver(
"ns2.cat.lol", null, "3-ROID", "v6", "bad:f00d:cafe::15:beef", "rdap_host.json")); "ns2.cat.lol", null, "4-ROID", "v6", "bad:f00d:cafe::15:beef", "rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -265,7 +267,7 @@ public class RdapNameserverSearchActionTest {
assertThat(generateActualJsonWithName("ns1.cat.external")) assertThat(generateActualJsonWithName("ns1.cat.external"))
.isEqualTo( .isEqualTo(
generateExpectedJsonForNameserver( generateExpectedJsonForNameserver(
"ns1.cat.external", null, "5-ROID", null, null, "rdap_host_external.json")); "ns1.cat.external", null, "8-ROID", null, null, "rdap_host_external.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -279,12 +281,14 @@ public class RdapNameserverSearchActionTest {
@Test @Test
public void testNameMatch_ns1_cat_idn_punycode_found() throws Exception { public void testNameMatch_ns1_cat_idn_punycode_found() throws Exception {
assertThat(generateActualJsonWithName("ns1.cat.xn--q9jyb4c")) assertThat(generateActualJsonWithName("ns1.cat.xn--q9jyb4c"))
.isEqualTo(generateExpectedJsonForNameserver( .isEqualTo(
"ns1.cat.みんな", "ns1.cat.xn--q9jyb4c", generateExpectedJsonForNameserver(
"7-ROID", "ns1.cat.みんな",
"v4", "ns1.cat.xn--q9jyb4c",
"1.2.3.5", "B-ROID",
"rdap_host_unicode.json")); "v4",
"1.2.3.5",
"rdap_host_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -293,7 +297,7 @@ public class RdapNameserverSearchActionTest {
assertThat(generateActualJsonWithName("ns1.cat.1.test")) assertThat(generateActualJsonWithName("ns1.cat.1.test"))
.isEqualTo( .isEqualTo(
generateExpectedJsonForNameserver( generateExpectedJsonForNameserver(
"ns1.cat.1.test", null, "9-ROID", "v4", "1.2.3.6", "rdap_host.json")); "ns1.cat.1.test", null, "E-ROID", "v4", "1.2.3.6", "rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
@ -380,7 +384,7 @@ public class RdapNameserverSearchActionTest {
assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef")) assertThat(generateActualJsonWithIp("bad:f00d:cafe::15:beef"))
.isEqualTo( .isEqualTo(
generateExpectedJsonForNameserver( generateExpectedJsonForNameserver(
"ns2.cat.lol", null, "3-ROID", "v6", "bad:f00d:cafe::15:beef", "rdap_host.json")); "ns2.cat.lol", null, "4-ROID", "v6", "bad:f00d:cafe::15:beef", "rdap_host.json"));
assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getStatus()).isEqualTo(200);
} }
} }

View file

@ -11,6 +11,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -14,12 +14,27 @@
"value": "https://example.com/rdap/domain/%NAME%" "value": "https://example.com/rdap/domain/%NAME%"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers": [ "nameservers": [
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "5-ROID", "handle": "8-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns1.cat.lol", "href": "https://example.com/rdap/nameserver/ns1.cat.lol",
@ -34,13 +49,20 @@
"1.2.3.4" "1.2.3.4"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
}, },
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "6-ROID", "handle": "A-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns2.cat.lol", "href": "https://example.com/rdap/nameserver/ns2.cat.lol",
@ -55,6 +77,13 @@
"bad:f00d:cafe::15:beef" "bad:f00d:cafe::15:beef"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
} }
], ],
@ -64,16 +93,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "3-ROID", "handle": "4-ROID",
"roles": [ "roles": [
"administrative" "administrative"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/3-ROID", "href": "https://example.com/rdap/entity/4-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/3-ROID" "value": "https://example.com/rdap/entity/4-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -145,16 +181,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "4-ROID", "handle": "6-ROID",
"roles": [ "roles": [
"technical" "technical"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/4-ROID", "href": "https://example.com/rdap/entity/6-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/4-ROID" "value": "https://example.com/rdap/entity/6-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -238,6 +281,13 @@
"value": "https://example.com/rdap/entity/2-ROID" "value": "https://example.com/rdap/entity/2-ROID"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "entity", "objectClassName": "entity",
"vcardArray": [ "vcardArray": [
"vcard", "vcard",

View file

@ -15,12 +15,27 @@
"value": "https://example.com/rdap/domain/%PUNYCODENAME%" "value": "https://example.com/rdap/domain/%PUNYCODENAME%"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers": [ "nameservers": [
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "5-ROID", "handle": "8-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns1.cat.lol", "href": "https://example.com/rdap/nameserver/ns1.cat.lol",
@ -35,13 +50,20 @@
"1.2.3.4" "1.2.3.4"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
}, },
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "6-ROID", "handle": "A-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns2.cat.lol", "href": "https://example.com/rdap/nameserver/ns2.cat.lol",
@ -56,6 +78,13 @@
"bad:f00d:cafe::15:beef" "bad:f00d:cafe::15:beef"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
} }
], ],
@ -65,16 +94,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "3-ROID", "handle": "4-ROID",
"roles": [ "roles": [
"administrative" "administrative"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/3-ROID", "href": "https://example.com/rdap/entity/4-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/3-ROID" "value": "https://example.com/rdap/entity/4-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -146,16 +182,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "4-ROID", "handle": "6-ROID",
"roles": [ "roles": [
"technical" "technical"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/4-ROID", "href": "https://example.com/rdap/entity/6-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/4-ROID" "value": "https://example.com/rdap/entity/6-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -239,6 +282,13 @@
"value": "https://example.com/rdap/entity/2-ROID" "value": "https://example.com/rdap/entity/2-ROID"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "entity", "objectClassName": "entity",
"vcardArray": [ "vcardArray": [
"vcard", "vcard",

View file

@ -17,6 +17,13 @@
"%ADDRESS%" "%ADDRESS%"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"objectClassName": "nameserver", "objectClassName": "nameserver",
"port43": "whois.example.tld" "port43": "whois.example.tld"
} }

View file

@ -12,6 +12,13 @@
} }
], ],
"ldhName": "%NAME%", "ldhName": "%NAME%",
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"objectClassName": "nameserver", "objectClassName": "nameserver",
"port43": "whois.example.tld" "port43": "whois.example.tld"
} }

View file

@ -18,6 +18,13 @@
"%ADDRESS%" "%ADDRESS%"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"objectClassName": "nameserver", "objectClassName": "nameserver",
"port43": "whois.example.tld" "port43": "whois.example.tld"
} }

View file

@ -14,6 +14,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -53,6 +60,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "2-Registrar",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"publicIds" : "publicIds" :
[ [
{ {

View file

@ -7,7 +7,7 @@
"transfer prohibited", "transfer prohibited",
"update prohibited" "update prohibited"
], ],
"handle": "13-EXAMPLE", "handle": "21-EXAMPLE",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/domain/cat.example", "href": "https://example.com/rdap/domain/cat.example",
@ -16,12 +16,27 @@
"value": "https://example.com/rdap/domain/cat.example" "value": "https://example.com/rdap/domain/cat.example"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers": [ "nameservers": [
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "5-ROID", "handle": "8-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns1.cat.lol", "href": "https://example.com/rdap/nameserver/ns1.cat.lol",
@ -36,13 +51,20 @@
"1.2.3.4" "1.2.3.4"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
}, },
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "12-ROID", "handle": "1F-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns2.external.tld", "href": "https://example.com/rdap/nameserver/ns2.external.tld",
@ -57,6 +79,13 @@
"bad:f00d:cafe::15:beef" "bad:f00d:cafe::15:beef"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
} }
], ],
@ -66,16 +95,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "10-ROID", "handle": "1B-ROID",
"roles": [ "roles": [
"administrative" "administrative"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/10-ROID", "href": "https://example.com/rdap/entity/1B-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/10-ROID" "value": "https://example.com/rdap/entity/1B-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -147,16 +183,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "11-ROID", "handle": "1D-ROID",
"roles": [ "roles": [
"technical" "technical"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/11-ROID", "href": "https://example.com/rdap/entity/1D-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/11-ROID" "value": "https://example.com/rdap/entity/1D-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -228,16 +271,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "F-ROID", "handle": "19-ROID",
"roles": [ "roles": [
"registrant" "registrant"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/F-ROID", "href": "https://example.com/rdap/entity/19-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/F-ROID" "value": "https://example.com/rdap/entity/19-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -316,7 +366,7 @@
"transfer prohibited", "transfer prohibited",
"update prohibited" "update prohibited"
], ],
"handle": "7-LOL", "handle": "C-LOL",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/domain/cat.lol", "href": "https://example.com/rdap/domain/cat.lol",
@ -325,12 +375,27 @@
"value": "https://example.com/rdap/domain/cat.lol" "value": "https://example.com/rdap/domain/cat.lol"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers": [ "nameservers": [
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "5-ROID", "handle": "8-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns1.cat.lol", "href": "https://example.com/rdap/nameserver/ns1.cat.lol",
@ -345,13 +410,20 @@
"1.2.3.4" "1.2.3.4"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
}, },
{ {
"status": [ "status": [
"active" "active"
], ],
"handle": "6-ROID", "handle": "A-ROID",
"links": [ "links": [
{ {
"href": "https://example.com/rdap/nameserver/ns2.cat.lol", "href": "https://example.com/rdap/nameserver/ns2.cat.lol",
@ -366,6 +438,13 @@
"bad:f00d:cafe::15:beef" "bad:f00d:cafe::15:beef"
] ]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"objectClassName": "nameserver" "objectClassName": "nameserver"
} }
], ],
@ -375,16 +454,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "3-ROID", "handle": "4-ROID",
"roles": [ "roles": [
"administrative" "administrative"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/3-ROID", "href": "https://example.com/rdap/entity/4-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/3-ROID" "value": "https://example.com/rdap/entity/4-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -456,16 +542,23 @@
"status": [ "status": [
"active" "active"
], ],
"handle": "4-ROID", "handle": "6-ROID",
"roles": [ "roles": [
"technical" "technical"
], ],
"links": [ "links": [
{ {
"href": "https://example.com/rdap/entity/4-ROID", "href": "https://example.com/rdap/entity/6-ROID",
"type": "application/rdap+json", "type": "application/rdap+json",
"rel": "self", "rel": "self",
"value": "https://example.com/rdap/entity/4-ROID" "value": "https://example.com/rdap/entity/6-ROID"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
} }
], ],
"objectClassName": "entity", "objectClassName": "entity",
@ -549,6 +642,13 @@
"value": "https://example.com/rdap/entity/2-ROID" "value": "https://example.com/rdap/entity/2-ROID"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"objectClassName": "entity", "objectClassName": "entity",
"vcardArray": [ "vcardArray": [
"vcard", "vcard",

View file

@ -3,7 +3,7 @@
[ [
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "3-ROID", "handle" : "4-ROID",
"status" : ["active"], "status" : ["active"],
"ldhName" : "ns2.cat.lol", "ldhName" : "ns2.cat.lol",
"links" : "links" :
@ -19,11 +19,18 @@
{ {
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"port43": "whois.example.tld" "port43": "whois.example.tld"
}, },
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "4-ROID", "handle" : "6-ROID",
"status" : ["active"], "status" : ["active"],
"ldhName" : "ns1.cat2.lol", "ldhName" : "ns1.cat2.lol",
"links" : "links" :
@ -40,6 +47,13 @@
"v4" : ["1.2.3.3"] "v4" : ["1.2.3.3"]
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]
}, },
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"port43": "whois.example.tld" "port43": "whois.example.tld"
} }
], ],

View file

@ -19,6 +19,13 @@
"identifier" : "1" "identifier" : "1"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "%NAME%",
"eventDate": "2000-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -1,17 +1,24 @@
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "3-ROID", "handle" : "4-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["administrative"], "roles" : ["administrative"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/3-ROID", "value" : "http://myserver.google.com/entity/4-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/3-ROID", "href" : "http://myserver.google.com/entity/4-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "domain", "objectClassName" : "domain",
"handle" : "9-Q9JYB4C", "handle" : "10-Q9JYB4C",
"ldhName" : "cat.xn--q9jyb4c", "ldhName" : "cat.xn--q9jyb4c",
"unicodeName" : "cat.みんな", "unicodeName" : "cat.みんな",
"status" : "status" :
@ -19,11 +19,26 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers" : "nameservers" :
[ [
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "5-ROID", "handle" : "8-ROID",
"ldhName" : "ns1.cat.xn--q9jyb4c", "ldhName" : "ns1.cat.xn--q9jyb4c",
"unicodeName" : "ns1.cat.みんな", "unicodeName" : "ns1.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -36,6 +51,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.4"] "v4" : ["1.2.3.4"]
@ -43,7 +65,7 @@
}, },
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "6-ROID", "handle" : "A-ROID",
"ldhName" : "ns2.cat.xn--q9jyb4c", "ldhName" : "ns2.cat.xn--q9jyb4c",
"unicodeName" : "ns2.cat.みんな", "unicodeName" : "ns2.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -56,6 +78,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"ipAddresses" : "ipAddresses" :
{ {
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]
@ -66,18 +95,25 @@
[ [
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "3-ROID", "handle" : "4-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["administrative"], "roles" : ["administrative"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/3-ROID", "value" : "http://myserver.google.com/entity/4-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/3-ROID", "href" : "http://myserver.google.com/entity/4-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -104,18 +140,25 @@
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "4-ROID", "handle" : "6-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["technical"], "roles" : ["technical"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/4-ROID", "value" : "http://myserver.google.com/entity/6-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/4-ROID", "href" : "http://myserver.google.com/entity/6-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -154,6 +197,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "domain", "objectClassName" : "domain",
"handle" : "B-Q9JYB4C", "handle" : "12-Q9JYB4C",
"ldhName" : "bird.xn--q9jyb4c", "ldhName" : "bird.xn--q9jyb4c",
"unicodeName" : "bird.みんな", "unicodeName" : "bird.みんな",
"status" : "status" :
@ -19,11 +19,26 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers" : "nameservers" :
[ [
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "5-ROID", "handle" : "8-ROID",
"ldhName" : "ns1.cat.xn--q9jyb4c", "ldhName" : "ns1.cat.xn--q9jyb4c",
"unicodeName" : "ns1.cat.みんな", "unicodeName" : "ns1.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -36,6 +51,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.4"] "v4" : ["1.2.3.4"]
@ -43,7 +65,7 @@
}, },
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "6-ROID", "handle" : "A-ROID",
"ldhName" : "ns2.cat.xn--q9jyb4c", "ldhName" : "ns2.cat.xn--q9jyb4c",
"unicodeName" : "ns2.cat.みんな", "unicodeName" : "ns2.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -56,6 +78,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"ipAddresses" : "ipAddresses" :
{ {
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "domain", "objectClassName" : "domain",
"handle" : "C-Q9JYB4C", "handle" : "13-Q9JYB4C",
"ldhName" : "fish.xn--q9jyb4c", "ldhName" : "fish.xn--q9jyb4c",
"unicodeName" : "fish.みんな", "unicodeName" : "fish.みんな",
"status" : "status" :
@ -20,22 +20,44 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"entities" : "entities" :
[ [
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "3-ROID", "handle" : "4-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["administrative"], "roles" : ["administrative"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/3-ROID", "value" : "http://myserver.google.com/entity/4-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/3-ROID", "href" : "http://myserver.google.com/entity/4-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -62,18 +84,25 @@
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "4-ROID", "handle" : "6-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["technical"], "roles" : ["technical"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/4-ROID", "value" : "http://myserver.google.com/entity/6-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/4-ROID", "href" : "http://myserver.google.com/entity/6-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -112,6 +141,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "domain", "objectClassName" : "domain",
"handle" : "A-Q9JYB4C", "handle" : "11-Q9JYB4C",
"ldhName" : "dog.xn--q9jyb4c", "ldhName" : "dog.xn--q9jyb4c",
"unicodeName" : "dog.みんな", "unicodeName" : "dog.みんな",
"status" : "status" :
@ -19,11 +19,26 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2110-10-08T00:44:59.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2009-05-29T20:13:00.000Z"
}
],
"nameservers" : "nameservers" :
[ [
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "7-ROID", "handle" : "C-ROID",
"ldhName" : "ns3.cat.xn--q9jyb4c", "ldhName" : "ns3.cat.xn--q9jyb4c",
"unicodeName" : "ns3.cat.みんな", "unicodeName" : "ns3.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -36,6 +51,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
}
],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.4"] "v4" : ["1.2.3.4"]
@ -44,10 +66,17 @@
}, },
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "8-ROID", "handle" : "E-ROID",
"ldhName" : "ns4.cat.xn--q9jyb4c", "ldhName" : "ns4.cat.xn--q9jyb4c",
"unicodeName" : "ns4.cat.みんな", "unicodeName" : "ns4.cat.みんな",
"status" : ["active"], "status" : ["active"],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1996-01-01T00:00:00.000Z"
}
],
"links" : "links" :
[ [
{ {
@ -63,18 +92,25 @@
[ [
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "3-ROID", "handle" : "4-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["administrative"], "roles" : ["administrative"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/3-ROID", "value" : "http://myserver.google.com/entity/4-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/3-ROID", "href" : "http://myserver.google.com/entity/4-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",
@ -101,18 +137,25 @@
}, },
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "4-ROID", "handle" : "6-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["technical"], "roles" : ["technical"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/4-ROID", "value" : "http://myserver.google.com/entity/6-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/4-ROID", "href" : "http://myserver.google.com/entity/6-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
}
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "7-ROID", "handle" : "C-ROID",
"ldhName" : "ns3.cat.xn--q9jyb4c", "ldhName" : "ns3.cat.xn--q9jyb4c",
"unicodeName" : "ns3.cat.みんな", "unicodeName" : "ns3.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -13,6 +13,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
},
],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.4"], "v4" : ["1.2.3.4"],

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "5-ROID", "handle" : "8-ROID",
"ldhName" : "ns1.cat.xn--q9jyb4c", "ldhName" : "ns1.cat.xn--q9jyb4c",
"unicodeName" : "ns1.cat.みんな", "unicodeName" : "ns1.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -13,6 +13,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"ipAddresses" : "ipAddresses" :
{ {
"v4" : ["1.2.3.4"] "v4" : ["1.2.3.4"]

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "6-ROID", "handle" : "A-ROID",
"ldhName" : "ns2.cat.xn--q9jyb4c", "ldhName" : "ns2.cat.xn--q9jyb4c",
"unicodeName" : "ns2.cat.みんな", "unicodeName" : "ns2.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -13,6 +13,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
},
],
"ipAddresses" : "ipAddresses" :
{ {
"v6" : ["bad:f00d:cafe::15:beef"] "v6" : ["bad:f00d:cafe::15:beef"]

View file

@ -1,6 +1,6 @@
{ {
"objectClassName" : "nameserver", "objectClassName" : "nameserver",
"handle" : "8-ROID", "handle" : "E-ROID",
"ldhName" : "ns4.cat.xn--q9jyb4c", "ldhName" : "ns4.cat.xn--q9jyb4c",
"unicodeName" : "ns4.cat.みんな", "unicodeName" : "ns4.cat.みんな",
"status" : ["active"], "status" : ["active"],
@ -13,5 +13,12 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1996-01-01T00:00:00.000Z"
},
],
"port43": "whois.google.com" "port43": "whois.google.com"
} }

View file

@ -12,6 +12,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -12,6 +12,13 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -12,6 +12,17 @@
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "unicoderegistrar",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "last changed",
"eventDate": "2000-01-01T00:00:00.000Z"
},
],
"publicIds" : "publicIds" :
[ [
{ {

View file

@ -1,17 +1,24 @@
{ {
"objectClassName" : "entity", "objectClassName" : "entity",
"handle" : "4-ROID", "handle" : "6-ROID",
"status" : ["active"], "status" : ["active"],
"roles" : ["technical"], "roles" : ["technical"],
"links" : "links" :
[ [
{ {
"value" : "http://myserver.google.com/entity/4-ROID", "value" : "http://myserver.google.com/entity/6-ROID",
"rel" : "self", "rel" : "self",
"href" : "http://myserver.google.com/entity/4-ROID", "href" : "http://myserver.google.com/entity/6-ROID",
"type" : "application/rdap+json" "type" : "application/rdap+json"
} }
], ],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1997-01-01T00:00:00.000Z"
},
],
"vcardArray" : "vcardArray" :
[ [
"vcard", "vcard",

View file

@ -17,23 +17,29 @@ package com.google.domain.registry.testing;
import static com.google.domain.registry.model.domain.DomainUtils.getTldFromDomainName; import static com.google.domain.registry.model.domain.DomainUtils.getTldFromDomainName;
import static com.google.domain.registry.testing.DatastoreHelper.generateNewContactHostRoid; import static com.google.domain.registry.testing.DatastoreHelper.generateNewContactHostRoid;
import static com.google.domain.registry.testing.DatastoreHelper.generateNewDomainRoid; import static com.google.domain.registry.testing.DatastoreHelper.generateNewDomainRoid;
import static com.google.domain.registry.testing.DatastoreHelper.persistResource;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.net.InetAddresses; import com.google.common.net.InetAddresses;
import com.google.domain.registry.model.EppResource;
import com.google.domain.registry.model.contact.ContactAddress; import com.google.domain.registry.model.contact.ContactAddress;
import com.google.domain.registry.model.contact.ContactPhoneNumber; import com.google.domain.registry.model.contact.ContactPhoneNumber;
import com.google.domain.registry.model.contact.ContactResource; import com.google.domain.registry.model.contact.ContactResource;
import com.google.domain.registry.model.contact.PostalInfo; import com.google.domain.registry.model.contact.PostalInfo;
import com.google.domain.registry.model.domain.DesignatedContact; import com.google.domain.registry.model.domain.DesignatedContact;
import com.google.domain.registry.model.domain.DomainResource; import com.google.domain.registry.model.domain.DomainResource;
import com.google.domain.registry.model.domain.Period;
import com.google.domain.registry.model.domain.ReferenceUnion; import com.google.domain.registry.model.domain.ReferenceUnion;
import com.google.domain.registry.model.domain.secdns.DelegationSignerData; import com.google.domain.registry.model.domain.secdns.DelegationSignerData;
import com.google.domain.registry.model.eppcommon.StatusValue; import com.google.domain.registry.model.eppcommon.StatusValue;
import com.google.domain.registry.model.eppcommon.Trid;
import com.google.domain.registry.model.host.HostResource; import com.google.domain.registry.model.host.HostResource;
import com.google.domain.registry.model.registrar.Registrar; import com.google.domain.registry.model.registrar.Registrar;
import com.google.domain.registry.model.registrar.RegistrarAddress; import com.google.domain.registry.model.registrar.RegistrarAddress;
import com.google.domain.registry.model.registrar.RegistrarContact; import com.google.domain.registry.model.registrar.RegistrarContact;
import com.google.domain.registry.model.reporting.HistoryEntry;
import com.google.domain.registry.util.Idn; import com.google.domain.registry.util.Idn;
import org.joda.time.DateTime; import org.joda.time.DateTime;
@ -128,6 +134,21 @@ public final class FullFieldsTestEntityHelper {
return builder.build(); return builder.build();
} }
public static HostResource makeAndPersistHostResource(
String fqhn, @Nullable String ip, @Nullable DateTime creationTime) {
return makeAndPersistHostResource(fqhn, ip, null, creationTime);
}
public static HostResource makeAndPersistHostResource(
String fqhn, @Nullable String ip1, @Nullable String ip2, @Nullable DateTime creationTime) {
HostResource hostResource = persistResource(makeHostResource(fqhn, ip1, ip2));
if (creationTime != null) {
persistResource(makeHistoryEntry(
hostResource, HistoryEntry.Type.HOST_CREATE, null, "created", creationTime));
}
return hostResource;
}
public static ContactResource makeContactResource( public static ContactResource makeContactResource(
String id, String name, @Nullable String email) { String id, String name, @Nullable String email) {
return makeContactResource( return makeContactResource(
@ -168,6 +189,26 @@ public final class FullFieldsTestEntityHelper {
return builder.build(); return builder.build();
} }
public static ContactResource makeAndPersistContactResource(
String id, String name, @Nullable String email, @Nullable DateTime creationTime) {
return makeAndPersistContactResource(
id, name, email, ImmutableList.of("123 Example Boulevard <script>"), creationTime);
}
public static ContactResource makeAndPersistContactResource(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime) {
ContactResource contactResource = persistResource(makeContactResource(id, name, email, street));
if (creationTime != null) {
persistResource(makeHistoryEntry(
contactResource, HistoryEntry.Type.CONTACT_CREATE, null, "created", creationTime));
}
return contactResource;
}
public static DomainResource makeDomainResource( public static DomainResource makeDomainResource(
String domain, String domain,
@Nullable ContactResource registrant, @Nullable ContactResource registrant,
@ -216,4 +257,24 @@ public final class FullFieldsTestEntityHelper {
} }
return builder.build(); return builder.build();
} }
public static HistoryEntry makeHistoryEntry(
EppResource resource,
HistoryEntry.Type type,
Period period,
String reason,
DateTime modificationTime) {
HistoryEntry.Builder builder = new HistoryEntry.Builder()
.setParent(resource)
.setType(type)
.setPeriod(period)
.setXmlBytes("<xml></xml>".getBytes(UTF_8))
.setModificationTime(modificationTime)
.setClientId("foo")
.setTrid(Trid.create("ABC-123"))
.setBySuperuser(false)
.setReason(reason)
.setRequestedByRegistrar(false);
return builder.build();
}
} }