Include GP statuses in RDAP results (#2606)

We do this for WHOIS results so we should do it for RDAP results as well
(especially since they're mostly already included in the response
profile).
This commit is contained in:
gbrodman
2024-12-09 19:55:16 +00:00
committed by GitHub
parent cb3738d540
commit 8e41278717
11 changed files with 987 additions and 56 deletions
@@ -42,9 +42,11 @@ import org.junit.jupiter.api.extension.RegisterExtension;
/** Common unit test code for actions inheriting {@link RdapActionBase}. */
abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
protected final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
@RegisterExtension
final JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
protected static final AuthResult AUTH_RESULT =
AuthResult.createUser(
@@ -61,7 +63,6 @@ abstract class RdapActionBaseTestCase<A extends RdapActionBase> {
.build());
protected FakeResponse response = new FakeResponse();
protected final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
final RdapMetrics rdapMetrics = mock(RdapMetrics.class);
RdapAuthorization.Role metricRole = PUBLIC;
@@ -17,6 +17,8 @@ package google.registry.rdap;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistDomainWithDependentResources;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.DatabaseHelper.persistSimpleResources;
import static google.registry.testing.FullFieldsTestEntityHelper.makeAndPersistHost;
@@ -31,7 +33,10 @@ import com.google.common.collect.ImmutableSet;
import com.google.gson.JsonObject;
import google.registry.model.contact.Contact;
import google.registry.model.domain.Domain;
import google.registry.model.domain.GracePeriod;
import google.registry.model.domain.Period;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host;
import google.registry.model.registrar.Registrar;
import google.registry.model.reporting.HistoryEntry;
@@ -43,6 +48,7 @@ import google.registry.rdap.RdapSearchResults.IncompletenessWarningType;
import google.registry.request.Action;
import google.registry.testing.FullFieldsTestEntityHelper;
import java.util.Optional;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -59,6 +65,9 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
super(RdapDomainAction.class);
}
private Contact registrantLol;
private Host host1;
@BeforeEach
void beforeEach() {
// lol
@@ -66,7 +75,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
Registrar registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarPocs(registrarLol));
Contact registrantLol =
registrantLol =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-ERL",
"Goblin Market",
@@ -83,7 +92,7 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
Contact techContactLol =
FullFieldsTestEntityHelper.makeAndPersistContact(
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3), registrarLol);
Host host1 = makeAndPersistHost("ns1.cat.lol", "1.2.3.4", null, clock.nowUtc().minusYears(1));
host1 = makeAndPersistHost("ns1.cat.lol", "1.2.3.4", null, clock.nowUtc().minusYears(1));
Host host2 =
makeAndPersistHost(
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
@@ -493,6 +502,93 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
void testAddGracePeriod() {
persistActiveDomainWithHost(
"addgraceperiod", "lol", clock.nowUtc(), clock.nowUtc().plusYears(1));
assertAboutJson()
.that(generateActualJson("addgraceperiod.lol"))
.isEqualTo(addBoilerplate(jsonFileBuilder().load("rdap_domain_add_grace_period.json")));
}
@Test
void testAutoRenewGracePeriod() {
persistActiveDomainWithHost(
"autorenew", "lol", clock.nowUtc().minusYears(1).minusDays(1), clock.nowUtc().minusDays(1));
assertAboutJson()
.that(generateActualJson("autorenew.lol"))
.isEqualTo(
addBoilerplate(jsonFileBuilder().load("rdap_domain_auto_renew_grace_period.json")));
}
@Test
void testRedemptionGracePeriod() {
Domain domain = persistActiveDomain("redemption.lol", clock.nowUtc().minusYears(1));
persistResource(
domain
.asBuilder()
.addNameserver(host1.createVKey())
.setDeletionTime(clock.nowUtc().plusDays(1))
.setStatusValues(ImmutableSet.of(StatusValue.PENDING_DELETE))
.setGracePeriods(
ImmutableSet.of(
GracePeriod.createWithoutBillingEvent(
GracePeriodStatus.REDEMPTION,
domain.getRepoId(),
clock.nowUtc().plusDays(4),
"TheRegistrar")))
.build());
assertAboutJson()
.that(generateActualJson("redemption.lol"))
.isEqualTo(
addBoilerplate(
jsonFileBuilder().load("rdap_domain_pending_delete_redemption_grace_period.json")));
}
@Test
void testRenewGracePeriod() {
Domain domain =
persistActiveDomainWithHost(
"renew", "lol", clock.nowUtc().minusYears(1), clock.nowUtc().plusYears(1));
persistResource(
domain
.asBuilder()
.addGracePeriod(
GracePeriod.create(
GracePeriodStatus.RENEW,
domain.getRepoId(),
clock.nowUtc().plusDays(1),
"TheRegistrar",
null))
.build());
assertAboutJson()
.that(generateActualJson("renew.lol"))
.isEqualTo(
addBoilerplate(jsonFileBuilder().load("rdap_domain_explicit_renew_grace_period.json")));
}
@Test
void testTransferGracePeriod() {
Domain domain =
persistActiveDomainWithHost(
"transfer", "lol", clock.nowUtc().minusMonths(6), clock.nowUtc().plusYears(1));
persistResource(
domain
.asBuilder()
.addGracePeriod(
GracePeriod.create(
GracePeriodStatus.TRANSFER,
domain.getRepoId(),
clock.nowUtc().plusDays(1),
"TheRegistrar",
null))
.build());
assertAboutJson()
.that(generateActualJson("transfer.lol"))
.isEqualTo(
addBoilerplate(jsonFileBuilder().load("rdap_domain_transfer_grace_period.json")));
}
@Test
void testMetrics() {
generateActualJson("cat.lol");
@@ -511,4 +607,14 @@ class RdapDomainActionTest extends RdapActionBaseTestCase<RdapDomainAction> {
.setIncompletenessWarningType(IncompletenessWarningType.COMPLETE)
.build());
}
private Domain persistActiveDomainWithHost(
String label, String tld, DateTime creationTime, DateTime expirationTime) {
return persistResource(
persistDomainWithDependentResources(
label, tld, registrantLol, clock.nowUtc(), creationTime, expirationTime)
.asBuilder()
.addNameserver(host1.createVKey())
.build());
}
}
@@ -124,6 +124,7 @@ import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
/** Static utils for setting up test resources. */
public final class DatabaseHelper {
@@ -593,30 +594,36 @@ public final class DatabaseHelper {
DateTime expirationTime) {
String domainName = String.format("%s.%s", label, tld);
String repoId = generateNewDomainRoid(tld);
Domain domain =
persistResource(
new Domain.Builder()
.setRepoId(repoId)
.setDomainName(domainName)
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setCreationRegistrarId("TheRegistrar")
.setCreationTimeForTest(creationTime)
.setRegistrationExpirationTime(expirationTime)
.setRegistrant(Optional.of(contact.createVKey()))
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
DesignatedContact.create(Type.TECH, contact.createVKey())))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("fooBAR")))
.addGracePeriod(
GracePeriod.create(
GracePeriodStatus.ADD, repoId, now.plusDays(10), "TheRegistrar", null))
.build());
Domain.Builder domainBuilder =
new Domain.Builder()
.setRepoId(repoId)
.setDomainName(domainName)
.setPersistedCurrentSponsorRegistrarId("TheRegistrar")
.setCreationRegistrarId("TheRegistrar")
.setCreationTimeForTest(creationTime)
.setRegistrationExpirationTime(expirationTime)
.setRegistrant(Optional.of(contact.createVKey()))
.setContacts(
ImmutableSet.of(
DesignatedContact.create(Type.ADMIN, contact.createVKey()),
DesignatedContact.create(Type.TECH, contact.createVKey())))
.setAuthInfo(DomainAuthInfo.create(PasswordAuth.create("fooBAR")));
Duration addGracePeriodLength = Tld.get(tld).getAddGracePeriodLength();
if (creationTime.plus(addGracePeriodLength).isAfter(now)) {
domainBuilder.addGracePeriod(
GracePeriod.create(
GracePeriodStatus.ADD,
repoId,
creationTime.plus(addGracePeriodLength),
"TheRegistrar",
null));
}
Domain domain = persistResource(domainBuilder.build());
DomainHistory historyEntryDomainCreate =
persistResource(
new DomainHistory.Builder()
.setType(HistoryEntry.Type.DOMAIN_CREATE)
.setModificationTime(now)
.setModificationTime(creationTime)
.setDomain(domain)
.setRegistrarId(domain.getCreationRegistrarId())
.build());
@@ -108,9 +108,10 @@ public class ConsoleBulkDomainActionTest {
assertThat(fakeResponse.getStatus()).isEqualTo(SC_OK);
assertThat(fakeResponse.getPayload())
.isEqualTo(
"{\"example.tld\":{\"message\":\"Command completed"
+ " successfully\",\"responseCode\":1000}}");
assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc());
"""
{"example.tld":{"message":"Command completed successfully; action pending",\
"responseCode":1001}}""");
assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35));
}
@Test
@@ -132,8 +133,8 @@ public class ConsoleBulkDomainActionTest {
assertThat(fakeResponse.getStatus()).isEqualTo(SC_OK);
assertThat(fakeResponse.getPayload())
.isEqualTo(
"{\"example.tld\":{\"message\":\"Command completed"
+ " successfully\",\"responseCode\":1000}}");
"""
{"example.tld":{"message":"Command completed successfully","responseCode":1000}}""");
assertThat(loadByEntity(domain).getStatusValues())
.containsAtLeast(
StatusValue.SERVER_RENEW_PROHIBITED,
@@ -158,11 +159,11 @@ public class ConsoleBulkDomainActionTest {
assertThat(fakeResponse.getStatus()).isEqualTo(SC_OK);
assertThat(fakeResponse.getPayload())
.isEqualTo(
"{\"example.tld\":{\"message\":\"Command completed"
+ " successfully\",\"responseCode\":1000},\"nonexistent.tld\":{\"message\":\"The"
+ " domain with given ID (nonexistent.tld) doesn\\u0027t"
+ " exist.\",\"responseCode\":2303}}");
assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc());
"""
{"example.tld":{"message":"Command completed successfully; action pending","responseCode":1001},\
"nonexistent.tld":{"message":"The domain with given ID (nonexistent.tld) doesn\\u0027t exist.",\
"responseCode":2303}}""");
assertThat(loadByEntity(domain).getDeletionTime()).isEqualTo(clock.nowUtc().plusDays(35));
}
@Test
@@ -0,0 +1,161 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"entities": [
{
"objectClassName": "entity",
"handle": "1",
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"rel": "self",
"type": "application/rdap+json"
}
],
"publicIds": [
{
"identifier": "1",
"type": "IANA Registrar ID"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
],
"roles": [
"registrar"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
"The Registrar"
]
]
]
},
{
"objectClassName": "entity",
"handle": "",
"remarks": [
{
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"links": [
{
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel": "alternate",
"type": "text/html"
}
],
"title": "REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
},
{
"description": [
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
],
"title": "EMAIL REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
}
],
"roles": [
"administrative",
"technical",
"registrant"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
""
]
]
]
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "TheRegistrar",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2001-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"handle": "28-LOL",
"ldhName": "addgraceperiod.lol",
"links": [
{
"href": "https://example.tld/rdap/domain/addgraceperiod.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"nameservers": [
{
"objectClassName": "nameserver",
"handle": "8-ROID",
"ldhName": "ns1.cat.lol",
"links": [
{
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
]
}
],
"secureDNS": {
"delegationSigned": false,
"zoneSigned": true
},
"status": [
"active",
"add period"
]
}
@@ -0,0 +1,165 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"entities": [
{
"objectClassName": "entity",
"handle": "1",
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"rel": "self",
"type": "application/rdap+json"
}
],
"publicIds": [
{
"identifier": "1",
"type": "IANA Registrar ID"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
],
"roles": [
"registrar"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
"The Registrar"
]
]
]
},
{
"objectClassName": "entity",
"handle": "",
"remarks": [
{
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"links": [
{
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel": "alternate",
"type": "text/html"
}
],
"title": "REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
},
{
"description": [
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
],
"title": "EMAIL REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
}
],
"roles": [
"administrative",
"technical",
"registrant"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
""
]
]
]
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "TheRegistrar",
"eventDate": "1998-12-31T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2000-12-31T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
},
{
"eventAction": "last changed",
"eventDate": "1999-12-31T00:00:00.000Z"
}
],
"handle": "28-LOL",
"ldhName": "autorenew.lol",
"links": [
{
"href": "https://example.tld/rdap/domain/autorenew.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"nameservers": [
{
"objectClassName": "nameserver",
"handle": "8-ROID",
"ldhName": "ns1.cat.lol",
"links": [
{
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
]
}
],
"secureDNS": {
"delegationSigned": false,
"zoneSigned": true
},
"status": [
"active",
"auto renew period"
]
}
@@ -0,0 +1,161 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"entities": [
{
"objectClassName": "entity",
"handle": "1",
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"rel": "self",
"type": "application/rdap+json"
}
],
"publicIds": [
{
"identifier": "1",
"type": "IANA Registrar ID"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
],
"roles": [
"registrar"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
"The Registrar"
]
]
]
},
{
"objectClassName": "entity",
"handle": "",
"remarks": [
{
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"links": [
{
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel": "alternate",
"type": "text/html"
}
],
"title": "REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
},
{
"description": [
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
],
"title": "EMAIL REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
}
],
"roles": [
"administrative",
"technical",
"registrant"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
""
]
]
]
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "TheRegistrar",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2001-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"handle": "28-LOL",
"ldhName": "renew.lol",
"links": [
{
"href": "https://example.tld/rdap/domain/renew.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"nameservers": [
{
"objectClassName": "nameserver",
"handle": "8-ROID",
"ldhName": "ns1.cat.lol",
"links": [
{
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
]
}
],
"secureDNS": {
"delegationSigned": false,
"zoneSigned": true
},
"status": [
"active",
"renew period"
]
}
@@ -0,0 +1,161 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"entities": [
{
"objectClassName": "entity",
"handle": "1",
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"rel": "self",
"type": "application/rdap+json"
}
],
"publicIds": [
{
"identifier": "1",
"type": "IANA Registrar ID"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
],
"roles": [
"registrar"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
"The Registrar"
]
]
]
},
{
"objectClassName": "entity",
"handle": "",
"remarks": [
{
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"links": [
{
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel": "alternate",
"type": "text/html"
}
],
"title": "REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
},
{
"description": [
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
],
"title": "EMAIL REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
}
],
"roles": [
"administrative",
"technical",
"registrant"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
""
]
]
]
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "TheRegistrar",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "294247-01-10T04:00:54.775Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"handle": "28-LOL",
"ldhName": "redemption.lol",
"links": [
{
"href": "https://example.tld/rdap/domain/redemption.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"nameservers": [
{
"objectClassName": "nameserver",
"handle": "8-ROID",
"ldhName": "ns1.cat.lol",
"links": [
{
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
]
}
],
"secureDNS": {
"delegationSigned": false,
"zoneSigned": true
},
"status": [
"pending delete",
"redemption period"
]
}
@@ -0,0 +1,161 @@
{
"rdapConformance": [
"rdap_level_0",
"icann_rdap_response_profile_0",
"icann_rdap_technical_implementation_guide_0"
],
"objectClassName": "domain",
"entities": [
{
"objectClassName": "entity",
"handle": "1",
"links": [
{
"href": "https://example.tld/rdap/entity/1",
"rel": "self",
"type": "application/rdap+json"
}
],
"publicIds": [
{
"identifier": "1",
"type": "IANA Registrar ID"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
],
"roles": [
"registrar"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
"The Registrar"
]
]
]
},
{
"objectClassName": "entity",
"handle": "",
"remarks": [
{
"description": [
"Some of the data in this object has been removed.",
"Contact personal data is visible only to the owning registrar."
],
"links": [
{
"href": "https://github.com/google/nomulus/blob/master/docs/rdap.md#authentication",
"rel": "alternate",
"type": "text/html"
}
],
"title": "REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
},
{
"description": [
"Please query the RDDS service of the Registrar of Record identifies in this output for information on how to contact the Registrant of the queried domain name."
],
"title": "EMAIL REDACTED FOR PRIVACY",
"type": "object redacted due to authorization"
}
],
"roles": [
"administrative",
"technical",
"registrant"
],
"vcardArray": [
"vcard",
[
[
"version",
{},
"text",
"4.0"
],
[
"fn",
{},
"text",
""
]
]
]
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "TheRegistrar",
"eventDate": "1999-07-01T00:00:00.000Z"
},
{
"eventAction": "expiration",
"eventDate": "2001-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"handle": "28-LOL",
"ldhName": "transfer.lol",
"links": [
{
"href": "https://example.tld/rdap/domain/transfer.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"nameservers": [
{
"objectClassName": "nameserver",
"handle": "8-ROID",
"ldhName": "ns1.cat.lol",
"links": [
{
"href": "https://example.tld/rdap/nameserver/ns1.cat.lol",
"rel": "self",
"type": "application/rdap+json"
}
],
"remarks": [
{
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"title": "Incomplete Data",
"type": "object truncated due to unexplainable reasons"
}
]
}
],
"secureDNS": {
"delegationSigned": false,
"zoneSigned": true
},
"status": [
"active",
"transfer period"
]
}