Avoid showing personal contact data in RDAP when not logged in

This CL changes the RDAP responses. When the requester asks for information about a domain, and is not logged in as the owning registrar, no contact information is shown. When the requester asks for information about a contact, and is not logged in as the owner registrar, the existence of the contact is shown, but not any personal data (the existence is shown to make things easier to test).

The login uses the same functionality as the registrar console.

For the most part, this CL does not include the necessary tests to make sure that data is not returned when not logged in. The CL is so large that I didn't want to burden it further. Those tests will be added in a follow-on CL.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=168022034
This commit is contained in:
mountford 2017-09-08 11:24:21 -07:00 committed by jianglai
parent e892a2f0fe
commit c85dc0c089
23 changed files with 853 additions and 266 deletions

View file

@ -12,6 +12,7 @@ java_library(
"//java/google/registry/model",
"//java/google/registry/request",
"//java/google/registry/request/auth",
"//java/google/registry/ui/server/registrar",
"//java/google/registry/util",
"//third_party/java/objectify:objectify-v4_1",
"@com_google_auto_value",

View file

@ -33,6 +33,7 @@ import com.google.re2j.Pattern;
import com.googlecode.objectify.cmd.Query;
import google.registry.config.RegistryConfig.Config;
import google.registry.model.EppResource;
import google.registry.model.registrar.Registrar;
import google.registry.request.Action;
import google.registry.request.HttpException;
import google.registry.request.HttpException.BadRequestException;
@ -41,11 +42,15 @@ import google.registry.request.HttpException.UnprocessableEntityException;
import google.registry.request.RequestMethod;
import google.registry.request.RequestPath;
import google.registry.request.Response;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.ui.server.registrar.SessionUtils;
import google.registry.util.FormattingLogger;
import java.net.URI;
import java.net.URISyntaxException;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import org.json.simple.JSONValue;
/**
@ -66,9 +71,12 @@ public abstract class RdapActionBase implements Runnable {
private static final MediaType RESPONSE_MEDIA_TYPE = MediaType.create("application", "rdap+json");
@Inject HttpServletRequest request;
@Inject Response response;
@Inject @RequestMethod Action.Method requestMethod;
@Inject @RequestPath String requestPath;
@Inject AuthResult authResult;
@Inject SessionUtils sessionUtils;
@Inject RdapJsonFormatter rdapJsonFormatter;
@Inject @Config("rdapLinkBase") String rdapLinkBase;
@Inject @Config("rdapWhoisServer") @Nullable String rdapWhoisServer;
@ -142,6 +150,22 @@ public abstract class RdapActionBase implements Runnable {
}
}
Optional<String> getLoggedInClientId() {
if (!authResult.userAuthInfo().isPresent()) {
return Optional.<String>absent();
}
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
if (!sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)) {
return Optional.<String>absent();
}
String clientId = sessionUtils.getRegistrarClientId(request);
Optional<Registrar> registrar = Registrar.loadByClientIdCached(clientId);
if (!registrar.isPresent()) {
return Optional.<String>absent();
}
return Optional.of(clientId);
}
void validateDomainName(String name) {
try {
Optional<InternetDomainName> tld = findTldForName(InternetDomainName.from(name));

View file

@ -33,7 +33,7 @@ import org.joda.time.DateTime;
path = RdapDomainAction.PATH,
method = {GET, HEAD},
isPrefix = true,
auth = Auth.AUTH_PUBLIC_ANONYMOUS
auth = Auth.AUTH_PUBLIC
)
public class RdapDomainAction extends RdapActionBase {
@ -64,6 +64,12 @@ public class RdapDomainAction extends RdapActionBase {
throw new NotFoundException(pathSearchString + " not found");
}
return rdapJsonFormatter.makeRdapJsonForDomain(
domainResource, true, rdapLinkBase, rdapWhoisServer, now, OutputDataType.FULL);
domainResource,
true,
rdapLinkBase,
rdapWhoisServer,
now,
OutputDataType.FULL,
getLoggedInClientId());
}
}

View file

@ -65,7 +65,7 @@ import org.joda.time.DateTime;
@Action(
path = RdapDomainSearchAction.PATH,
method = {GET, HEAD},
auth = Auth.AUTH_PUBLIC_ANONYMOUS
auth = Auth.AUTH_PUBLIC
)
public class RdapDomainSearchAction extends RdapActionBase {
@ -375,11 +375,12 @@ public class RdapDomainSearchAction extends RdapActionBase {
List<DomainResource> domains, boolean isTruncated, DateTime now) {
OutputDataType outputDataType =
(domains.size() > 1) ? OutputDataType.SUMMARY : OutputDataType.FULL;
Optional<String> loggedInClientId = getLoggedInClientId();
ImmutableList.Builder<ImmutableMap<String, Object>> jsonBuilder = new ImmutableList.Builder<>();
for (DomainResource domain : domains) {
jsonBuilder.add(
rdapJsonFormatter.makeRdapJsonForDomain(
domain, false, rdapLinkBase, rdapWhoisServer, now, outputDataType));
domain, false, rdapLinkBase, rdapWhoisServer, now, outputDataType, loggedInClientId));
}
return RdapSearchResults.create(jsonBuilder.build(), isTruncated);
}

View file

@ -50,7 +50,7 @@ import org.joda.time.DateTime;
path = RdapEntityAction.PATH,
method = {GET, HEAD},
isPrefix = true,
auth = Auth.AUTH_PUBLIC_ANONYMOUS
auth = Auth.AUTH_PUBLIC
)
public class RdapEntityAction extends RdapActionBase {
@ -93,7 +93,8 @@ public class RdapEntityAction extends RdapActionBase {
rdapLinkBase,
rdapWhoisServer,
now,
OutputDataType.FULL);
OutputDataType.FULL,
getLoggedInClientId());
}
}
Long ianaIdentifier = Longs.tryParse(pathSearchString);

View file

@ -60,7 +60,7 @@ import org.joda.time.DateTime;
@Action(
path = RdapEntitySearchAction.PATH,
method = {GET, HEAD},
auth = Auth.AUTH_PUBLIC_ANONYMOUS
auth = Auth.AUTH_PUBLIC
)
public class RdapEntitySearchAction extends RdapActionBase {
@ -254,6 +254,7 @@ public class RdapEntitySearchAction extends RdapActionBase {
// There can be more results than our max size, partially because we have two pools to draw from
// (contacts and registrars), and partially because we try to fetch one more than the max size,
// so we can tell whether to display the truncation notification.
Optional<String> loggedInClientId = getLoggedInClientId();
List<ImmutableMap<String, Object>> jsonOutputList = new ArrayList<>();
for (ContactResource contact : contacts) {
if (jsonOutputList.size() >= rdapResultSetMaxSize) {
@ -268,7 +269,8 @@ public class RdapEntitySearchAction extends RdapActionBase {
rdapLinkBase,
rdapWhoisServer,
now,
outputDataType));
outputDataType,
loggedInClientId));
}
for (Registrar registrar : registrars) {
if (registrar.isActiveAndPubliclyVisible()) {

View file

@ -104,4 +104,24 @@ public class RdapIcannStandardInformation {
/** Truncation notice as a singleton list, for easy use. */
static final ImmutableList<ImmutableMap<String, Object>> TRUNCATION_NOTICES =
ImmutableList.of(TRUNCATED_RESULT_SET_NOTICE);
/** Included when the requester is not logged in as the owner of the domain being returned. */
static final ImmutableMap<String, Object> DOMAIN_CONTACTS_HIDDEN_DATA_REMARK =
ImmutableMap.<String, Object> of(
"title",
"Contacts Hidden",
"description",
ImmutableList.of("Domain contacts are visible only to the owning registrar."),
"type",
"object truncated due to unexplainable reasons");
/** Included when requester is not logged in as the owner of the contact being returned. */
static final ImmutableMap<String, Object> CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK =
ImmutableMap.<String, Object> of(
"title",
"Contact Personal Data Hidden",
"description",
ImmutableList.of("Contact personal data is visible only to the owning registrar."),
"type",
"object truncated due to unexplainable reasons");
}

View file

@ -444,6 +444,8 @@ public class RdapJsonFormatter {
* port43 field; if null, port43 is not added to the object
* @param now the as-date
* @param outputDataType whether to generate full or summary data
* @param loggedInClientId the logged-in client ID (or null if not logged in); if the requester is
* not logged in as the registrar owning the domain, no contact information is included
*/
ImmutableMap<String, Object> makeRdapJsonForDomain(
DomainResource domainResource,
@ -451,7 +453,8 @@ public class RdapJsonFormatter {
@Nullable String linkBase,
@Nullable String whoisServer,
DateTime now,
OutputDataType outputDataType) {
OutputDataType outputDataType,
Optional<String> loggedInClientId) {
// Start with the domain-level information.
ImmutableMap.Builder<String, Object> jsonBuilder = new ImmutableMap.Builder<>();
jsonBuilder.put("objectClassName", "domain");
@ -464,6 +467,8 @@ public class RdapJsonFormatter {
jsonBuilder.put("status", makeStatusValueList(domainResource.getStatusValues()));
jsonBuilder.put("links", ImmutableList.of(
makeLink("domain", domainResource.getFullyQualifiedDomainName(), linkBase)));
boolean displayContacts = loggedInClientId.isPresent()
&& loggedInClientId.get().equals(domainResource.getCurrentSponsorClientId());
// If we are outputting all data (not just summary data), also add information about hosts,
// contacts and events (history entries). If we are outputting summary data, instead add a
// remark indicating that fact.
@ -471,31 +476,24 @@ public class RdapJsonFormatter {
if (outputDataType == OutputDataType.SUMMARY) {
remarks = ImmutableList.of(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
} else {
remarks = ImmutableList.of();
remarks = displayContacts
? ImmutableList.<ImmutableMap<String, Object>>of()
: ImmutableList.of(RdapIcannStandardInformation.DOMAIN_CONTACTS_HIDDEN_DATA_REMARK);
ImmutableList<Object> events = makeEvents(domainResource, now);
if (!events.isEmpty()) {
jsonBuilder.put("events", events);
}
// Kick off the database loads of the nameservers that we will need.
// Kick off the database loads of the nameservers that we will need, so it can load
// asynchronously while we load and process the contacts.
Map<Key<HostResource>, HostResource> loadedHosts =
ofy().load().keys(domainResource.getNameservers());
// And the registrant and other contacts.
// Load the registrant and other contacts and add them to the data.
if (displayContacts) {
Map<Key<ContactResource>, ContactResource> loadedContacts =
ofy().load().keys(domainResource.getReferencedContacts());
// Nameservers
ImmutableList.Builder<Object> nsBuilder = new ImmutableList.Builder<>();
for (HostResource hostResource
: HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
nsBuilder.add(makeRdapJsonForHost(
hostResource, false, linkBase, null, now, outputDataType));
}
ImmutableList<Object> ns = nsBuilder.build();
if (!ns.isEmpty()) {
jsonBuilder.put("nameservers", ns);
}
// Contacts
ImmutableList.Builder<Object> entitiesBuilder = new ImmutableList.Builder<>();
for (DesignatedContact designatedContact : FluentIterable.from(domainResource.getContacts())
for (DesignatedContact designatedContact :
FluentIterable.from(domainResource.getContacts())
.append(DesignatedContact.create(Type.REGISTRANT, domainResource.getRegistrant()))
.toSortedList(DESIGNATED_CONTACT_ORDERING)) {
ContactResource loadedContact = loadedContacts.get(designatedContact.getContactKey());
@ -506,13 +504,26 @@ public class RdapJsonFormatter {
linkBase,
null,
now,
outputDataType));
outputDataType,
loggedInClientId));
}
ImmutableList<Object> entities = entitiesBuilder.build();
if (!entities.isEmpty()) {
jsonBuilder.put("entities", entities);
}
}
// Add the nameservers to the data; the load was kicked off above for efficiency.
ImmutableList.Builder<Object> nsBuilder = new ImmutableList.Builder<>();
for (HostResource hostResource
: HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) {
nsBuilder.add(makeRdapJsonForHost(
hostResource, false, linkBase, null, now, outputDataType));
}
ImmutableList<Object> ns = nsBuilder.build();
if (!ns.isEmpty()) {
jsonBuilder.put("nameservers", ns);
}
}
if (whoisServer != null) {
jsonBuilder.put("port43", whoisServer);
}
@ -633,6 +644,8 @@ public class RdapJsonFormatter {
* port43 field; if null, port43 is not added to the object
* @param now the as-date
* @param outputDataType whether to generate full or summary data
* @param loggedInClientId the logged-in client ID (or null if not logged in); personal contact
* data is only shown if the contact is owned by the logged-in client
*/
ImmutableMap<String, Object> makeRdapJsonForContact(
ContactResource contactResource,
@ -641,8 +654,11 @@ public class RdapJsonFormatter {
@Nullable String linkBase,
@Nullable String whoisServer,
DateTime now,
OutputDataType outputDataType) {
OutputDataType outputDataType,
Optional<String> loggedInClientId) {
ImmutableMap.Builder<String, Object> jsonBuilder = new ImmutableMap.Builder<>();
ImmutableList.Builder<ImmutableMap<String, Object>> remarksBuilder
= new ImmutableList.Builder<>();
jsonBuilder.put("objectClassName", "entity");
jsonBuilder.put("handle", contactResource.getRepoId());
jsonBuilder.put("status", makeStatusValueList(
@ -655,7 +671,9 @@ public class RdapJsonFormatter {
}
jsonBuilder.put("links",
ImmutableList.of(makeLink("entity", contactResource.getRepoId(), linkBase)));
// Create the vCard.
// If we are logged in as the owner of this contact, create the vCard.
if (loggedInClientId.isPresent()
&& loggedInClientId.get().equals(contactResource.getCurrentSponsorClientId())) {
ImmutableList.Builder<Object> vcardBuilder = new ImmutableList.Builder<>();
vcardBuilder.add(VCARD_ENTRY_VERSION);
PostalInfo postalInfo = contactResource.getInternationalizedPostalInfo();
@ -687,13 +705,14 @@ public class RdapJsonFormatter {
vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress));
}
jsonBuilder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build()));
} else {
remarksBuilder.add(RdapIcannStandardInformation.CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK);
}
// If we are outputting all data (not just summary data), also add events taken from the history
// entries. If we are outputting summary data, instead add a remark indicating that fact.
List<ImmutableMap<String, Object>> remarks;
if (outputDataType == OutputDataType.SUMMARY) {
remarks = ImmutableList.of(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
remarksBuilder.add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK);
} else {
remarks = ImmutableList.of();
ImmutableList<Object> events = makeEvents(contactResource, now);
if (!events.isEmpty()) {
jsonBuilder.put("events", events);
@ -706,12 +725,15 @@ public class RdapJsonFormatter {
addTopLevelEntries(
jsonBuilder,
BoilerplateType.ENTITY,
remarks,
remarksBuilder.build(),
ImmutableList.<ImmutableMap<String, Object>>of(),
linkBase);
} else if (!remarks.isEmpty()) {
} else {
ImmutableList<ImmutableMap<String, Object>> remarks = remarksBuilder.build();
if (!remarks.isEmpty()) {
jsonBuilder.put(REMARKS, remarks);
}
}
return jsonBuilder.build();
}

View file

@ -32,7 +32,8 @@ public final class RdapUtils {
new Predicate<Registrar>() {
@Override
public boolean apply(Registrar registrar) {
return registrar.getIanaIdentifier() == ianaIdentifier;
Long registrarIanaIdentifier = registrar.getIanaIdentifier();
return (registrarIanaIdentifier != null) && (registrarIanaIdentifier == ianaIdentifier);
}});
}
}

View file

@ -3,10 +3,10 @@ PATH CLASS METHODS OK AUTH_METHODS
/_dr/whois WhoisServer POST n INTERNAL,API APP ADMIN
/check CheckApiAction GET n INTERNAL NONE PUBLIC
/rdap/autnum/(*) RdapAutnumAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/domain/(*) RdapDomainAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/domains RdapDomainSearchAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/entities RdapEntitySearchAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/entity/(*) RdapEntityAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/domain/(*) RdapDomainAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC
/rdap/domains RdapDomainSearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC
/rdap/entities RdapEntitySearchAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC
/rdap/entity/(*) RdapEntityAction GET,HEAD n INTERNAL,API,LEGACY NONE PUBLIC
/rdap/help(*) RdapHelpAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/ip/(*) RdapIpAction GET,HEAD n INTERNAL NONE PUBLIC
/rdap/nameserver/(*) RdapNameserverAction GET,HEAD n INTERNAL NONE PUBLIC

View file

@ -16,6 +16,8 @@ java_library(
"//java/google/registry/model",
"//java/google/registry/rdap",
"//java/google/registry/request",
"//java/google/registry/request/auth",
"//java/google/registry/ui/server/registrar",
"//javatests/google/registry/testing",
"//third_party/java/objectify:objectify-v4_1",
"@com_google_appengine_api_1_0_sdk//:testonly",

View file

@ -25,7 +25,10 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntr
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.contact.ContactResource;
@ -36,11 +39,18 @@ import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.ui.server.registrar.SessionUtils;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.Before;
@ -62,8 +72,11 @@ public class RdapDomainActionTest {
@Rule
public final InjectRule inject = new InjectRule();
private final HttpServletRequest request = mock(HttpServletRequest.class);
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
private final SessionUtils sessionUtils = mock(SessionUtils.class);
private final User user = new User("rdap.user@example.com", "gmail.com", "12345");
private RdapDomainAction action;
@ -75,57 +88,111 @@ public class RdapDomainActionTest {
Registrar registrarLol = persistResource(makeRegistrar(
"evilregistrar", "Yes Virginia <script>", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarContacts(registrarLol));
ContactResource registrant = makeAndPersistContactResource(
"5372808-ERL", "Goblin Market", "lol@cat.lol", clock.nowUtc().minusYears(1));
ContactResource adminContact = makeAndPersistContactResource(
"5372808-IRL", "Santa Claus", "BOFH@cat.lol", clock.nowUtc().minusYears(2));
ContactResource techContact = makeAndPersistContactResource(
"5372808-TRL", "The Raven", "bog@cat.lol", clock.nowUtc().minusYears(3));
ContactResource registrantLol =
makeAndPersistContactResource(
"5372808-ERL",
"Goblin Market",
"lol@cat.lol",
clock.nowUtc().minusYears(1),
registrarLol);
ContactResource adminContactLol =
makeAndPersistContactResource(
"5372808-IRL",
"Santa Claus",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2),
registrarLol);
ContactResource techContactLol =
makeAndPersistContactResource(
"5372808-TRL",
"The Raven",
"bog@cat.lol",
clock.nowUtc().minusYears(3),
registrarLol);
HostResource host1 = makeAndPersistHostResource(
"ns1.cat.lol", "1.2.3.4", clock.nowUtc().minusYears(1));
"ns1.cat.lol", "1.2.3.4", null, clock.nowUtc().minusYears(1));
HostResource host2 = makeAndPersistHostResource(
"ns2.cat.lol", "bad:f00d:cafe:0:0:0:15:beef", clock.nowUtc().minusYears(2));
DomainBase domainCatLol =
persistResource(makeDomainResource("cat.lol",
registrant, adminContact, techContact, host1, host2, registrarLol));
registrantLol, adminContactLol, techContactLol, host1, host2, registrarLol));
// deleted domain in lol
DomainBase domainDeleted = persistResource(makeDomainResource("dodo.lol",
registrant,
adminContact,
techContact,
registrantLol,
adminContactLol,
techContactLol,
host1,
host2,
registrarLol).asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
// xn--q9jyb4c
createTld("xn--q9jyb4c");
Registrar registrarIdn =
persistResource(makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarContacts(registrarIdn));
ContactResource registrantIdn =
makeAndPersistContactResource(
"5372808-ERL",
"Goblin Market",
"lol@cat.lol",
clock.nowUtc().minusYears(1),
registrarIdn);
ContactResource adminContactIdn =
makeAndPersistContactResource(
"5372808-IRL",
"Santa Claus",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2),
registrarIdn);
ContactResource techContactIdn =
makeAndPersistContactResource(
"5372808-TRL",
"The Raven",
"bog@cat.lol",
clock.nowUtc().minusYears(3),
registrarIdn);
DomainBase domainCatIdn = persistResource(makeDomainResource("cat.みんな",
registrant,
adminContact,
techContact,
registrantIdn,
adminContactIdn,
techContactIdn,
host1,
host2,
registrarIdn));
// 1.tld
createTld("1.tld");
Registrar registrar1tld = persistResource(
Registrar registrar1Tld = persistResource(
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE));
persistSimpleResources(makeRegistrarContacts(registrar1tld));
persistSimpleResources(makeRegistrarContacts(registrar1Tld));
ContactResource registrant1Tld =
makeAndPersistContactResource(
"5372808-ERL",
"Goblin Market",
"lol@cat.lol",
clock.nowUtc().minusYears(1),
registrar1Tld);
ContactResource adminContact1Tld =
makeAndPersistContactResource(
"5372808-IRL",
"Santa Claus",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2),
registrar1Tld);
ContactResource techContact1Tld =
makeAndPersistContactResource(
"5372808-TRL",
"The Raven",
"bog@cat.lol",
clock.nowUtc().minusYears(3),
registrar1Tld);
DomainBase domainCat1Tld = persistResource(makeDomainResource("cat.1.tld",
registrant,
adminContact,
techContact,
registrant1Tld,
adminContact1Tld,
techContact1Tld,
host1,
host2,
registrar1tld));
action = new RdapDomainAction();
action.clock = clock;
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = null;
registrar1Tld));
// history entries
persistResource(
@ -156,6 +223,19 @@ public class RdapDomainActionTest {
Period.create(1, Period.Unit.YEARS),
"created",
clock.nowUtc()));
action = new RdapDomainAction();
action.clock = clock;
action.request = request;
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils;
UserAuthInfo userAuthInfo = UserAuthInfo.create(user, false);
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
when(sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn("evilregistrar");
}
private Object generateActualJson(String domainName) {
@ -169,23 +249,38 @@ public class RdapDomainActionTest {
String punycodeName,
String handle,
String expectedOutputFile) {
return JSONValue.parse(loadFileWithSubstitutions(
this.getClass(),
expectedOutputFile,
ImmutableMap.of(
"NAME", name,
"PUNYCODENAME", (punycodeName == null) ? name : punycodeName,
"HANDLE", handle,
"TYPE", "domain name")));
return generateExpectedJson(name, punycodeName, handle, null, expectedOutputFile);
}
private Object generateExpectedJson(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
String expectedOutputFile) {
ImmutableMap.Builder<String, String> substitutionsBuilder = new ImmutableMap.Builder<>();
substitutionsBuilder.put("NAME", name);
substitutionsBuilder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
substitutionsBuilder.put("HANDLE", handle);
substitutionsBuilder.put("TYPE", "domain name");
if (contactRoids != null) {
for (int i = 0; i < contactRoids.size(); i++) {
substitutionsBuilder.put("CONTACT" + (i + 1) + "ROID", contactRoids.get(i));
}
}
return JSONValue.parse(
loadFileWithSubstitutions(
this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
}
private Object generateExpectedJsonWithTopLevelEntries(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
String expectedOutputFile) {
Object obj = generateExpectedJson(
name, punycodeName, handle, expectedOutputFile);
name, punycodeName, handle, contactRoids, expectedOutputFile);
if (obj instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) obj;
@ -205,9 +300,20 @@ public class RdapDomainActionTest {
return obj;
}
private void assertJsonEqual(Object json1, Object json2) {
if (json1 instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) json1;
assertThat(map).isEqualTo(json2);
} else {
assertThat(json1).isEqualTo(json2);
}
}
@Test
public void testInvalidDomain_returns400() throws Exception {
assertThat(generateActualJson("invalid/domain/name")).isEqualTo(
assertJsonEqual(
generateActualJson("invalid/domain/name"),
generateExpectedJson(
"invalid/domain/name is not a valid domain name", null, "1", "rdap_error_400.json"));
assertThat(response.getStatus()).isEqualTo(400);
@ -215,67 +321,112 @@ public class RdapDomainActionTest {
@Test
public void testUnknownDomain_returns404() throws Exception {
assertThat(generateActualJson("missingdomain.com")).isEqualTo(
assertJsonEqual(
generateActualJson("missingdomain.com"),
generateExpectedJson("missingdomain.com not found", null, "1", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testDeletedDomain_returns404() throws Exception {
assertThat(generateActualJson("dodo.lol")).isEqualTo(
assertJsonEqual(
generateActualJson("dodo.lol"),
generateExpectedJson("dodo.lol not found", null, "1", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void testValidDomain_works() throws Exception {
assertThat(generateActualJson("cat.lol")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertJsonEqual(
generateActualJson("cat.lol"),
generateExpectedJsonWithTopLevelEntries(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testTrailingDot_ignored() throws Exception {
assertThat(generateActualJson("cat.lol.")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertJsonEqual(
generateActualJson("cat.lol."),
generateExpectedJsonWithTopLevelEntries(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testQueryParameter_ignored() throws Exception {
assertThat(generateActualJson("cat.lol?key=value")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.lol", null, "C-LOL", "rdap_domain.json"));
assertJsonEqual(
generateActualJson("cat.lol?key=value"),
generateExpectedJsonWithTopLevelEntries(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testIdnDomain_works() throws Exception {
assertThat(generateActualJson("cat.みんな")).isEqualTo(
when(sessionUtils.getRegistrarClientId(request)).thenReturn("idnregistrar");
assertJsonEqual(
generateActualJson("cat.みんな"),
generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
"cat.みんな",
"cat.xn--q9jyb4c",
"15-Q9JYB4C",
ImmutableList.of("11-ROID", "13-ROID", "F-ROID"),
"rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testIdnDomainWithPercentEncoding_works() throws Exception {
assertThat(generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA")).isEqualTo(
when(sessionUtils.getRegistrarClientId(request)).thenReturn("idnregistrar");
assertJsonEqual(
generateActualJson("cat.%E3%81%BF%E3%82%93%E3%81%AA"),
generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
"cat.みんな",
"cat.xn--q9jyb4c",
"15-Q9JYB4C",
ImmutableList.of("11-ROID", "13-ROID", "F-ROID"),
"rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testPunycodeDomain_works() throws Exception {
assertThat(generateActualJson("cat.xn--q9jyb4c")).isEqualTo(
when(sessionUtils.getRegistrarClientId(request)).thenReturn("idnregistrar");
assertJsonEqual(
generateActualJson("cat.xn--q9jyb4c"),
generateExpectedJsonWithTopLevelEntries(
"cat.みんな", "cat.xn--q9jyb4c", "F-Q9JYB4C", "rdap_domain_unicode.json"));
"cat.みんな",
"cat.xn--q9jyb4c",
"15-Q9JYB4C",
ImmutableList.of("11-ROID", "13-ROID", "F-ROID"),
"rdap_domain_unicode.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test
public void testMultilevelDomain_works() throws Exception {
assertThat(generateActualJson("cat.1.tld")).isEqualTo(
generateExpectedJsonWithTopLevelEntries("cat.1.tld", null, "11-1.TLD", "rdap_domain.json"));
when(sessionUtils.getRegistrarClientId(request)).thenReturn("1tldregistrar");
assertJsonEqual(
generateActualJson("cat.1.tld"),
generateExpectedJsonWithTopLevelEntries(
"cat.1.tld",
null,
"1D-1.TLD",
ImmutableList.of("19-ROID", "1B-ROID", "17-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}

View file

@ -27,7 +27,10 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeHistoryEntr
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ -43,12 +46,18 @@ import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
import google.registry.model.reporting.HistoryEntry;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.ui.server.registrar.SessionUtils;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.Before;
@ -70,8 +79,11 @@ public class RdapDomainSearchActionTest {
@Rule
public final InjectRule inject = new InjectRule();
private final HttpServletRequest request = mock(HttpServletRequest.class);
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final SessionUtils sessionUtils = mock(SessionUtils.class);
private final User user = new User("rdap.user@example.com", "gmail.com", "12345");
private final RdapDomainSearchAction action = new RdapDomainSearchAction();
@ -132,17 +144,20 @@ public class RdapDomainSearchActionTest {
"5372808-ERL",
"Goblin Market",
"lol@cat.lol",
clock.nowUtc().minusYears(1)),
clock.nowUtc().minusYears(1),
registrar),
contact2 = makeAndPersistContactResource(
"5372808-IRL",
"Santa Claus",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2)),
clock.nowUtc().minusYears(2),
registrar),
contact3 = makeAndPersistContactResource(
"5372808-TRL",
"The Raven",
"bog@cat.lol",
clock.nowUtc().minusYears(3)),
clock.nowUtc().minusYears(3),
registrar),
hostNs1CatLol = makeAndPersistHostResource(
"ns1.cat.lol",
"1.2.3.4",
@ -167,17 +182,20 @@ public class RdapDomainSearchActionTest {
"6372808-ERL",
"Siegmund",
"siegmund@cat2.lol",
clock.nowUtc().minusYears(1)),
clock.nowUtc().minusYears(1),
registrar),
makeAndPersistContactResource(
"6372808-IRL",
"Sieglinde",
"sieglinde@cat2.lol",
clock.nowUtc().minusYears(2)),
clock.nowUtc().minusYears(2),
registrar),
makeAndPersistContactResource(
"6372808-TRL",
"Siegfried",
"siegfried@cat2.lol",
clock.nowUtc().minusYears(3)),
clock.nowUtc().minusYears(3),
registrar),
makeAndPersistHostResource(
"ns1.cat.example", "10.20.30.40", clock.nowUtc().minusYears(1)),
makeAndPersistHostResource(
@ -198,17 +216,20 @@ public class RdapDomainSearchActionTest {
"7372808-ERL",
"Matthew",
"lol@cat.lol",
clock.nowUtc().minusYears(1)),
clock.nowUtc().minusYears(1),
registrar),
makeAndPersistContactResource(
"7372808-IRL",
"Mark",
"BOFH@cat.lol",
clock.nowUtc().minusYears(2)),
clock.nowUtc().minusYears(2),
registrar),
makeAndPersistContactResource(
"7372808-TRL",
"Luke",
"bog@cat.lol",
clock.nowUtc().minusYears(3)),
clock.nowUtc().minusYears(3),
registrar),
hostNs1CatLol,
makeAndPersistHostResource(
"ns2.external.tld", "bad:f00d:cafe::15:beef", clock.nowUtc().minusYears(2)),
@ -227,17 +248,20 @@ public class RdapDomainSearchActionTest {
"8372808-ERL",
"(◕‿◕)",
"lol@cat.みんな",
clock.nowUtc().minusYears(1)),
clock.nowUtc().minusYears(1),
registrar),
makeAndPersistContactResource(
"8372808-IRL",
"Santa Claus",
"BOFH@cat.みんな",
clock.nowUtc().minusYears(2)),
clock.nowUtc().minusYears(2),
registrar),
makeAndPersistContactResource(
"8372808-TRL",
"The Raven",
"bog@cat.みんな",
clock.nowUtc().minusYears(3)),
clock.nowUtc().minusYears(3),
registrar),
makeAndPersistHostResource("ns1.cat.みんな", "1.2.3.5", clock.nowUtc().minusYears(1)),
makeAndPersistHostResource(
"ns2.cat.みんな", "bad:f00d:cafe::14:beef", clock.nowUtc().minusYears(2)),
@ -256,17 +280,20 @@ public class RdapDomainSearchActionTest {
"9372808-ERL",
"(◕‿◕)",
"lol@cat.みんな",
clock.nowUtc().minusYears(1)),
clock.nowUtc().minusYears(1),
registrar),
makeAndPersistContactResource(
"9372808-IRL",
"Santa Claus",
"BOFH@cat.みんな",
clock.nowUtc().minusYears(2)),
clock.nowUtc().minusYears(2),
registrar),
makeAndPersistContactResource(
"9372808-TRL",
"The Raven",
"bog@cat.みんな",
clock.nowUtc().minusYears(3)),
clock.nowUtc().minusYears(3),
registrar),
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)),
@ -300,10 +327,16 @@ public class RdapDomainSearchActionTest {
clock.nowUtc()));
action.clock = clock;
action.request = request;
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils;
UserAuthInfo userAuthInfo = UserAuthInfo.create(user, false);
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
when(sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn("evilregistrar");
}
private Object generateExpectedJson(String expectedOutputFile) {
@ -313,27 +346,38 @@ public class RdapDomainSearchActionTest {
ImmutableMap.of("TYPE", "domain name")));
}
private Object generateExpectedJson(String name, String expectedOutputFile) {
return generateExpectedJson(name, null, null, null, expectedOutputFile);
}
private Object generateExpectedJson(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
String expectedOutputFile) {
return JSONValue.parse(loadFileWithSubstitutions(
this.getClass(),
expectedOutputFile,
ImmutableMap.of(
"NAME", name,
"PUNYCODENAME", (punycodeName == null) ? name : punycodeName,
"HANDLE", (handle == null) ? "(null)" : handle,
"TYPE", "domain name")));
ImmutableMap.Builder<String, String> substitutionsBuilder = new ImmutableMap.Builder<>();
substitutionsBuilder.put("NAME", name);
substitutionsBuilder.put("PUNYCODENAME", (punycodeName == null) ? name : punycodeName);
substitutionsBuilder.put("HANDLE", (handle == null) ? "(null)" : handle);
substitutionsBuilder.put("TYPE", "domain name");
if (contactRoids != null) {
for (int i = 0; i < contactRoids.size(); i++) {
substitutionsBuilder.put("CONTACT" + (i + 1) + "ROID", contactRoids.get(i));
}
}
return JSONValue.parse(
loadFileWithSubstitutions(
this.getClass(), expectedOutputFile, substitutionsBuilder.build()));
}
private Object generateExpectedJsonForDomain(
String name,
String punycodeName,
String handle,
@Nullable List<String> contactRoids,
String expectedOutputFile) {
Object obj = generateExpectedJson(name, punycodeName, handle, expectedOutputFile);
Object obj = generateExpectedJson(name, punycodeName, handle, contactRoids, expectedOutputFile);
ImmutableMap.Builder<String, Object> builder = new ImmutableMap.Builder<>();
builder.put("domainSearchResults", ImmutableList.of(obj));
builder.put("rdapConformance", ImmutableList.of("rdap_level_0"));
@ -354,8 +398,6 @@ public class RdapDomainSearchActionTest {
assertThat(generateActualJson(RequestType.NONE, null))
.isEqualTo(generateExpectedJson(
"You must specify either name=XXXX, nsLdhName=YYYY or nsIp=ZZZZ",
null,
null,
"rdap_error_400.json"));
assertThat(response.getStatus()).isEqualTo(400);
}
@ -366,8 +408,6 @@ public class RdapDomainSearchActionTest {
.isEqualTo(generateExpectedJson(
"Suffix after wildcard must be one or more domain"
+ " name labels, e.g. exam*.tld, ns*.example.tld",
null,
null,
"rdap_error_422.json"));
assertThat(response.getStatus()).isEqualTo(422);
}
@ -375,8 +415,7 @@ public class RdapDomainSearchActionTest {
@Test
public void testMultipleWildcards_rejected() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "*.*"))
.isEqualTo(generateExpectedJson(
"Only one wildcard allowed", null, null, "rdap_error_422.json"));
.isEqualTo(generateExpectedJson("Only one wildcard allowed", "rdap_error_422.json"));
assertThat(response.getStatus()).isEqualTo(422);
}
@ -387,8 +426,6 @@ public class RdapDomainSearchActionTest {
generateExpectedJson(
"Initial search string is required for wildcard domain searches without a TLD"
+ " suffix",
null,
null,
"rdap_error_422.json"));
assertThat(response.getStatus()).isEqualTo(422);
}
@ -400,8 +437,6 @@ public class RdapDomainSearchActionTest {
generateExpectedJson(
"Initial search string must be at least 2 characters for wildcard domain searches"
+ " without a TLD suffix",
null,
null,
"rdap_error_422.json"));
assertThat(response.getStatus()).isEqualTo(422);
}
@ -409,7 +444,13 @@ public class RdapDomainSearchActionTest {
@Test
public void testDomainMatch_found() throws Exception {
assertThat(generateActualJson(RequestType.NAME, "cat.lol"))
.isEqualTo(generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
.isEqualTo(
generateExpectedJsonForDomain(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@ -521,7 +562,7 @@ public class RdapDomainSearchActionTest {
public void testDomainMatchDeletedDomain_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NAME, "cat.lol"))
.isEqualTo(generateExpectedJson("No domains found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No domains found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -529,7 +570,7 @@ public class RdapDomainSearchActionTest {
public void testDomainMatchDeletedDomainWithWildcard_notFound() throws Exception {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NAME, "cat.lo*"))
.isEqualTo(generateExpectedJson("No domains found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No domains found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -733,7 +774,12 @@ public class RdapDomainSearchActionTest {
public void testNameserverMatchWithWildcard_found() throws Exception {
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns2.cat.l*"))
.isEqualTo(
generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
generateExpectedJsonForDomain(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@ -835,7 +881,12 @@ public class RdapDomainSearchActionTest {
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(
generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
generateExpectedJsonForDomain(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@ -844,7 +895,7 @@ public class RdapDomainSearchActionTest {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(generateExpectedJson("No domains found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No domains found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -853,8 +904,7 @@ public class RdapDomainSearchActionTest {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.lol"))
.isEqualTo(generateExpectedJson(
"No matching nameservers found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No matching nameservers found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -863,8 +913,7 @@ public class RdapDomainSearchActionTest {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat.l*"))
.isEqualTo(generateExpectedJson(
"No matching nameservers found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No matching nameservers found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -873,8 +922,7 @@ public class RdapDomainSearchActionTest {
persistResource(
hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJson(RequestType.NS_LDH_NAME, "ns1.cat*.lol"))
.isEqualTo(generateExpectedJson(
"No matching nameservers found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No matching nameservers found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -1015,7 +1063,12 @@ public class RdapDomainSearchActionTest {
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(
generateExpectedJsonForDomain("cat.lol", null, "C-LOL", "rdap_domain.json"));
generateExpectedJsonForDomain(
"cat.lol",
null,
"C-LOL",
ImmutableList.of("4-ROID", "6-ROID", "2-ROID"),
"rdap_domain.json"));
assertThat(response.getStatus()).isEqualTo(200);
}
@ -1024,7 +1077,7 @@ public class RdapDomainSearchActionTest {
persistDomainAsDeleted(domainCatLol, clock.nowUtc().minusDays(1));
persistDomainAsDeleted(domainCatExample, clock.nowUtc().minusDays(1));
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(generateExpectedJson("No domains found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No domains found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}
@ -1032,7 +1085,7 @@ public class RdapDomainSearchActionTest {
public void testAddressMatchDeletedNameserver_notFound() throws Exception {
persistResource(hostNs1CatLol.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
assertThat(generateActualJson(RequestType.NS_IP, "1.2.3.4"))
.isEqualTo(generateExpectedJson("No domains found", null, null, "rdap_error_404.json"));
.isEqualTo(generateExpectedJson("No domains found", "rdap_error_404.json"));
assertThat(response.getStatus()).isEqualTo(404);
}

View file

@ -25,18 +25,26 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeHostResourc
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.model.contact.ContactResource;
import google.registry.model.host.HostResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.ui.server.registrar.SessionUtils;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.Before;
@ -57,8 +65,11 @@ public class RdapEntityActionTest {
@Rule
public final InjectRule inject = new InjectRule();
private final HttpServletRequest request = mock(HttpServletRequest.class);
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01TZ"));
private final SessionUtils sessionUtils = mock(SessionUtils.class);
private final User user = new User("rdap.user@example.com", "gmail.com", "12345");
private RdapEntityAction action;
@ -82,19 +93,22 @@ public class RdapEntityActionTest {
"(◕‿◕)",
"lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"),
clock.nowUtc());
clock.nowUtc(),
registrarLol);
adminContact = makeAndPersistContactResource(
"8372808-ADM",
"(◕‿◕)",
"lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"),
clock.nowUtc());
clock.nowUtc(),
registrarLol);
techContact = makeAndPersistContactResource(
"8372808-TEC",
"(◕‿◕)",
"lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"),
clock.nowUtc());
clock.nowUtc(),
registrarLol);
HostResource host1 =
persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4"));
HostResource host2 =
@ -111,42 +125,38 @@ public class RdapEntityActionTest {
Registrar registrarIdn = persistResource(
makeRegistrar("idnregistrar", "IDN Registrar", Registrar.State.ACTIVE, 102L));
persistSimpleResources(makeRegistrarContacts(registrarIdn));
persistResource(makeDomainResource("cat.みんな",
registrant,
adminContact,
techContact,
host1,
host2,
registrarIdn));
// 1.tld
createTld("1.tld");
Registrar registrar1tld = persistResource(
makeRegistrar("1tldregistrar", "Multilevel Registrar", Registrar.State.ACTIVE, 103L));
persistSimpleResources(makeRegistrarContacts(registrar1tld));
persistResource(makeDomainResource("cat.1.tld",
registrant,
adminContact,
techContact,
host1,
host2,
registrar1tld));
// other contacts
disconnectedContact = makeAndPersistContactResource(
"8372808-DIS",
"(◕‿◕)",
"lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"),
clock.nowUtc());
clock.nowUtc(),
registrarLol);
deletedContact = persistResource(makeContactResource(
"8372808-DEL",
"(◕‿◕)",
"lol@cat.みんな",
ImmutableList.of("1 Smiley Row", "Suite みんな"))
ImmutableList.of("1 Smiley Row", "Suite みんな"),
registrarLol)
.asBuilder().setDeletionTime(clock.nowUtc()).build());
action = new RdapEntityAction();
action.clock = clock;
action.request = request;
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
action.rdapLinkBase = "https://example.com/rdap/";
action.rdapWhoisServer = null;
action.sessionUtils = sessionUtils;
UserAuthInfo userAuthInfo = UserAuthInfo.create(user, false);
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
when(sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn("evilregistrar");
}
private Object generateActualJson(String name) {

View file

@ -24,7 +24,10 @@ import static google.registry.testing.FullFieldsTestEntityHelper.makeContactReso
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrar;
import static google.registry.testing.FullFieldsTestEntityHelper.makeRegistrarContacts;
import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@ -32,13 +35,18 @@ import google.registry.model.ImmutableObject;
import google.registry.model.contact.ContactResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
import google.registry.request.auth.AuthLevel;
import google.registry.request.auth.AuthResult;
import google.registry.request.auth.UserAuthInfo;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.InjectRule;
import google.registry.ui.server.registrar.SessionUtils;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.json.simple.JSONValue;
import org.junit.Before;
@ -54,13 +62,16 @@ public class RdapEntitySearchActionTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Rule public final InjectRule inject = new InjectRule();
private final HttpServletRequest request = mock(HttpServletRequest.class);
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock(DateTime.parse("2000-01-01T00:00:00Z"));
private final SessionUtils sessionUtils = mock(SessionUtils.class);
private final User user = new User("rdap.user@example.com", "gmail.com", "12345");
private final RdapEntitySearchAction action = new RdapEntitySearchAction();
private ContactResource contact;
private Registrar registrar;
private Registrar registrarDeleted;
private Registrar registrarInactive;
private Registrar registrarTest;
@ -82,29 +93,11 @@ public class RdapEntitySearchActionTest {
createTld("tld");
contact = makeAndPersistContactResource(
"blinky",
"Blinky (赤ベイ)",
"blinky@b.tld",
ImmutableList.of("123 Blinky St", "Blinkyland"),
clock.nowUtc());
makeAndPersistContactResource(
"blindly",
"Blindly",
"blindly@b.tld",
ImmutableList.of("123 Blindly St", "Blindlyland"),
clock.nowUtc());
// deleted
persistResource(
makeContactResource("clyde", "Clyde (愚図た)", "clyde@c.tld")
.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
registrar =
registrarDeleted =
persistResource(
makeRegistrar("2-Registrar", "Yes Virginia <script>", Registrar.State.ACTIVE, 20L));
persistSimpleResources(makeRegistrarContacts(registrar));
persistSimpleResources(makeRegistrarContacts(registrarDeleted));
// inactive
registrarInactive =
@ -121,7 +114,28 @@ public class RdapEntitySearchActionTest {
.build());
persistSimpleResources(makeRegistrarContacts(registrarTest));
contact = makeAndPersistContactResource(
"blinky",
"Blinky (赤ベイ)",
"blinky@b.tld",
ImmutableList.of("123 Blinky St", "Blinkyland"),
clock.nowUtc(),
registrarTest);
makeAndPersistContactResource(
"blindly",
"Blindly",
"blindly@b.tld",
ImmutableList.of("123 Blindly St", "Blindlyland"),
clock.nowUtc(),
registrarTest);
persistResource(
makeContactResource("clyde", "Clyde (愚図た)", "clyde@c.tld", registrarDeleted)
.asBuilder().setDeletionTime(clock.nowUtc().minusDays(1)).build());
action.clock = clock;
action.request = request;
action.requestPath = RdapEntitySearchAction.PATH;
action.response = response;
action.rdapJsonFormatter = RdapTestHelper.getTestRdapJsonFormatter();
@ -130,6 +144,11 @@ public class RdapEntitySearchActionTest {
action.rdapWhoisServer = null;
action.fnParam = Optional.absent();
action.handleParam = Optional.absent();
action.sessionUtils = sessionUtils;
UserAuthInfo userAuthInfo = UserAuthInfo.create(user, false);
action.authResult = AuthResult.create(AuthLevel.USER, userAuthInfo);
when(sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)).thenReturn(true);
when(sessionUtils.getRegistrarClientId(request)).thenReturn("2-RegistrarTest");
}
private Object generateExpectedJson(String expectedOutputFile) {
@ -182,13 +201,15 @@ public class RdapEntitySearchActionTest {
return builder.build();
}
private void createManyContactsAndRegistrars(int numContacts, int numRegistrars) {
private void createManyContactsAndRegistrars(
int numContacts, int numRegistrars, Registrar contactRegistrar) {
ImmutableList.Builder<ImmutableObject> resourcesBuilder = new ImmutableList.Builder<>();
for (int i = 1; i <= numContacts; i++) {
resourcesBuilder.add(makeContactResource(
String.format("contact%d", i),
String.format("Entity %d", i),
String.format("contact%d@gmail.com", i)));
String.format("contact%d@gmail.com", i),
contactRegistrar));
}
persistResources(resourcesBuilder.build());
for (int i = 1; i <= numRegistrars; i++) {
@ -324,7 +345,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_nonTruncatedContacts() throws Exception {
createManyContactsAndRegistrars(4, 0);
createManyContactsAndRegistrars(4, 0, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_nontruncated_contacts.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -332,7 +353,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_truncatedContacts() throws Exception {
createManyContactsAndRegistrars(5, 0);
createManyContactsAndRegistrars(5, 0, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_truncated_contacts.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -340,7 +361,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_reallyTruncatedContacts() throws Exception {
createManyContactsAndRegistrars(9, 0);
createManyContactsAndRegistrars(9, 0, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_truncated_contacts.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -348,7 +369,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_nonTruncatedRegistrars() throws Exception {
createManyContactsAndRegistrars(0, 4);
createManyContactsAndRegistrars(0, 4, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_nontruncated_registrars.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -356,7 +377,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_truncatedRegistrars() throws Exception {
createManyContactsAndRegistrars(0, 5);
createManyContactsAndRegistrars(0, 5, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_truncated_registrars.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -364,7 +385,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_reallyTruncatedRegistrars() throws Exception {
createManyContactsAndRegistrars(0, 9);
createManyContactsAndRegistrars(0, 9, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_truncated_registrars.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -372,7 +393,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testNameMatch_truncatedMixOfContactsAndRegistrars() throws Exception {
createManyContactsAndRegistrars(3, 3);
createManyContactsAndRegistrars(3, 3, registrarTest);
assertThat(generateActualJsonWithFullName("Entity *"))
.isEqualTo(generateExpectedJson("rdap_truncated_mixed_entities.json"));
assertThat(response.getStatus()).isEqualTo(200);
@ -459,7 +480,7 @@ public class RdapEntitySearchActionTest {
@Test
public void testHandleMatch_truncatedEntities() throws Exception {
createManyContactsAndRegistrars(300, 0);
createManyContactsAndRegistrars(300, 0, registrarTest);
Object obj = generateActualJsonWithHandle("10*");
assertThat(response.getStatus()).isEqualTo(200);
checkNumberOfEntitiesInResult(obj, 4);

View file

@ -110,25 +110,29 @@ public class RdapJsonFormatterTest {
"(◕‿◕)",
"lol@cat.みんな",
null,
clock.nowUtc().minusYears(1));
clock.nowUtc().minusYears(1),
registrar);
contactResourceAdmin = makeAndPersistContactResource(
"8372808-IRL",
"Santa Claus",
null,
ImmutableList.of("Santa Claus Tower", "41st floor", "Suite みんな"),
clock.nowUtc().minusYears(2));
clock.nowUtc().minusYears(2),
registrar);
contactResourceTech = makeAndPersistContactResource(
"8372808-TRL",
"The Raven",
"bog@cat.みんな",
ImmutableList.of("Chamber Door", "upper level"),
clock.nowUtc().minusYears(3));
clock.nowUtc().minusYears(3),
registrar);
contactResourceNotLinked = makeAndPersistContactResource(
"8372808-QRL",
"The Wizard",
"dog@cat.みんな",
ImmutableList.of("Somewhere", "Over the Rainbow"),
clock.nowUtc().minusYears(4));
clock.nowUtc().minusYears(4),
registrar);
hostResourceIpv4 = makeAndPersistHostResource(
"ns1.cat.みんな", "1.2.3.4", clock.nowUtc().minusYears(1));
hostResourceIpv6 = makeAndPersistHostResource(
@ -365,7 +369,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_registrant.json"));
}
@ -379,10 +384,26 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY))
OutputDataType.SUMMARY,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_registrant_summary.json"));
}
@Test
public void testRegistrant_loggedOut() throws Exception {
assertThat(
rdapJsonFormatter.makeRdapJsonForContact(
contactResourceRegistrant,
false,
Optional.of(DesignatedContact.Type.REGISTRANT),
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
Optional.<String>absent()))
.isEqualTo(loadJson("rdapjson_registrant_logged_out.json"));
}
@Test
public void testRegistrant_baseHasNoTrailingSlash() throws Exception {
assertThat(
@ -393,7 +414,8 @@ public class RdapJsonFormatterTest {
LINK_BASE_NO_TRAILING_SLASH,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_registrant.json"));
}
@ -407,7 +429,8 @@ public class RdapJsonFormatterTest {
null,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_registrant_nobase.json"));
}
@ -421,7 +444,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_admincontact.json"));
}
@ -435,7 +459,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_techcontact.json"));
}
@ -449,7 +474,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_rolelesscontact.json"));
}
@ -463,7 +489,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_unlinkedcontact.json"));
}
@ -475,7 +502,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_domain_full.json"));
}
@ -487,10 +515,24 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.SUMMARY))
OutputDataType.SUMMARY,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_domain_summary.json"));
}
@Test
public void testDomain_logged_out() throws Exception {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
domainResourceFull,
false,
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL,
Optional.<String>absent()))
.isEqualTo(loadJson("rdapjson_domain_logged_out.json"));
}
@Test
public void testDomain_noNameservers() throws Exception {
assertThat(rdapJsonFormatter.makeRdapJsonForDomain(
@ -499,7 +541,8 @@ public class RdapJsonFormatterTest {
LINK_BASE,
WHOIS_SERVER,
clock.nowUtc(),
OutputDataType.FULL))
OutputDataType.FULL,
Optional.of("unicoderegistrar")))
.isEqualTo(loadJson("rdapjson_domain_no_nameservers.json"));
}

View file

@ -113,10 +113,11 @@ public class RdapNameserverSearchActionTest {
makeDomainResource(
"cat.lol",
persistResource(
makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol")),
makeContactResource("5372808-ERL", "Goblin Market", "lol@cat.lol", registrar)),
persistResource(
makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol")),
persistResource(makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol")),
makeContactResource("5372808-IRL", "Santa Claus", "BOFH@cat.lol", registrar)),
persistResource(
makeContactResource("5372808-TRL", "The Raven", "bog@cat.lol", registrar)),
hostNs1CatLol,
hostNs2CatLol,
registrar)

View file

@ -108,16 +108,16 @@
"active",
"associated"
],
"handle": "4-ROID",
"handle": "%CONTACT1ROID%",
"roles": [
"administrative"
],
"links": [
{
"href": "https://example.com/rdap/entity/4-ROID",
"href": "https://example.com/rdap/entity/%CONTACT1ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/4-ROID"
"value": "https://example.com/rdap/entity/%CONTACT1ROID%"
}
],
"events": [
@ -201,16 +201,16 @@
"active",
"associated"
],
"handle": "6-ROID",
"handle": "%CONTACT2ROID%",
"roles": [
"technical"
],
"links": [
{
"href": "https://example.com/rdap/entity/6-ROID",
"href": "https://example.com/rdap/entity/%CONTACT2ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/6-ROID"
"value": "https://example.com/rdap/entity/%CONTACT2ROID%"
}
],
"events": [
@ -294,16 +294,16 @@
"active",
"associated"
],
"handle": "2-ROID",
"handle": "%CONTACT3ROID%",
"roles": [
"registrant"
],
"links": [
{
"href": "https://example.com/rdap/entity/2-ROID",
"href": "https://example.com/rdap/entity/%CONTACT3ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/2-ROID"
"value": "https://example.com/rdap/entity/%CONTACT3ROID%"
}
],
"events": [

View file

@ -109,16 +109,16 @@
"active",
"associated"
],
"handle": "4-ROID",
"handle": "%CONTACT1ROID%",
"roles": [
"administrative"
],
"links": [
{
"href": "https://example.com/rdap/entity/4-ROID",
"href": "https://example.com/rdap/entity/%CONTACT1ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/4-ROID"
"value": "https://example.com/rdap/entity/%CONTACT1ROID%"
}
],
"events": [
@ -202,16 +202,16 @@
"active",
"associated"
],
"handle": "6-ROID",
"handle": "%CONTACT2ROID%",
"roles": [
"technical"
],
"links": [
{
"href": "https://example.com/rdap/entity/6-ROID",
"href": "https://example.com/rdap/entity/%CONTACT2ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/6-ROID"
"value": "https://example.com/rdap/entity/%CONTACT2ROID%"
}
],
"events": [
@ -295,16 +295,16 @@
"active",
"associated"
],
"handle": "2-ROID",
"handle": "%CONTACT3ROID%",
"roles": [
"registrant"
],
"links": [
{
"href": "https://example.com/rdap/entity/2-ROID",
"href": "https://example.com/rdap/entity/%CONTACT3ROID%",
"type": "application/rdap+json",
"rel": "self",
"value": "https://example.com/rdap/entity/2-ROID"
"value": "https://example.com/rdap/entity/%CONTACT3ROID%"
}
],
"events": [

View file

@ -0,0 +1,115 @@
{
"objectClassName" : "domain",
"handle" : "17-Q9JYB4C",
"ldhName" : "cat.xn--q9jyb4c",
"unicodeName" : "cat.みんな",
"status" :
[
"client delete prohibited",
"client renew prohibited",
"client transfer prohibited",
"server update prohibited"
],
"links" :
[
{
"value" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/domain/cat.xn--q9jyb4c",
"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"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"nameservers" :
[
{
"objectClassName" : "nameserver",
"handle" : "A-ROID",
"ldhName" : "ns1.cat.xn--q9jyb4c",
"unicodeName" : "ns1.cat.みんな",
"status" : ["active", "associated"],
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns1.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"ipAddresses" :
{
"v4" : ["1.2.3.4"]
}
},
{
"objectClassName" : "nameserver",
"handle" : "C-ROID",
"ldhName" : "ns2.cat.xn--q9jyb4c",
"unicodeName" : "ns2.cat.みんな",
"status" : ["active", "associated"],
"links" :
[
{
"value" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"rel" : "self",
"href" : "http://myserver.example.com/nameserver/ns2.cat.xn--q9jyb4c",
"type" : "application/rdap+json"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1998-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"ipAddresses" :
{
"v6" : ["bad:f00d:cafe::15:beef"]
}
}
],
"remarks": [
{
"title": "Contacts Hidden",
"description": [
"Domain contacts are visible only to the owning registrar."
],
"type": "object truncated due to unexplainable reasons"
}
]
}

View file

@ -0,0 +1,35 @@
{
"objectClassName" : "entity",
"handle" : "2-ROID",
"status" : ["active", "associated"],
"roles" : ["registrant"],
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"type" : "application/rdap+json"
}
],
"events": [
{
"eventAction": "registration",
"eventActor": "foo",
"eventDate": "1999-01-01T00:00:00.000Z"
},
{
"eventAction": "last update of RDAP database",
"eventDate": "2000-01-01T00:00:00.000Z"
}
],
"remarks": [
{
"title": "Contact Personal Data Hidden",
"description": [
"Contact personal data is visible only to the owning registrar."
],
"type": "object truncated due to unexplainable reasons"
}
]
}

View file

@ -0,0 +1,43 @@
{
"objectClassName" : "entity",
"handle" : "2-ROID",
"status" : ["active", "associated"],
"roles" : ["registrant"],
"links" :
[
{
"value" : "http://myserver.example.com/entity/2-ROID",
"rel" : "self",
"href" : "http://myserver.example.com/entity/2-ROID",
"type" : "application/rdap+json"
}
],
"vcardArray" :
[
"vcard",
[
["version", {}, "text", "4.0"],
["fn", {}, "text", "(◕‿◕)"],
["org", {}, "text", "GOOGLE INCORPORATED <script>"],
["tel", {"type" : ["voice"]}, "uri", "tel:+1.2126660420"],
["tel", {"type" : ["fax"]}, "uri", "tel:+1.2126660420"],
["email", {}, "text", "lol@cat.みんな"]
]
],
"remarks": [
{
"title": "Incomplete Data",
"description": [
"Summary data only. For complete data, send a specific query for the object."
],
"type": "object truncated due to unexplainable reasons"
},
{
"title": "Contact Personal Data Hidden",
"description": [
"Contact personal data is visible only to the owning registrar."
],
"type": "object truncated due to unexplainable reasons"
}
]
}

View file

@ -163,11 +163,21 @@ public final class FullFieldsTestEntityHelper {
public static ContactResource makeContactResource(
String id, String name, @Nullable String email) {
return makeContactResource(
id, name, email, ImmutableList.of("123 Example Boulevard <script>"));
id, name, email, ImmutableList.of("123 Example Boulevard <script>"), null);
}
public static ContactResource makeContactResource(
String id, String name, @Nullable String email, @Nullable List<String> street) {
String id, String name, @Nullable String email, @Nullable Registrar registrar) {
return makeContactResource(
id, name, email, ImmutableList.of("123 Example Boulevard <script>"), registrar);
}
public static ContactResource makeContactResource(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable Registrar registrar) {
PostalInfo.Builder postalBuilder = new PostalInfo.Builder()
.setType(PostalInfo.Type.INTERNATIONALIZED)
.setName(name)
@ -197,13 +207,27 @@ public final class FullFieldsTestEntityHelper {
if (email != null) {
builder.setEmailAddress(email);
}
if (registrar != null) {
builder
.setCreationClientId(registrar.getClientId())
.setPersistedCurrentSponsorClientId(registrar.getClientId());
}
return builder.build();
}
public static ContactResource makeAndPersistContactResource(
String id, String name, @Nullable String email, @Nullable DateTime creationTime) {
String id,
String name,
@Nullable String email,
@Nullable DateTime creationTime,
@Nullable Registrar registrar) {
return makeAndPersistContactResource(
id, name, email, ImmutableList.of("123 Example Boulevard <script>"), creationTime);
id,
name,
email,
ImmutableList.of("123 Example Boulevard <script>"),
creationTime,
registrar);
}
public static ContactResource makeAndPersistContactResource(
@ -212,7 +236,18 @@ public final class FullFieldsTestEntityHelper {
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime) {
ContactResource contactResource = persistResource(makeContactResource(id, name, email, street));
return makeAndPersistContactResource(id, name, email, street, creationTime, null);
}
public static ContactResource makeAndPersistContactResource(
String id,
String name,
@Nullable String email,
@Nullable List<String> street,
@Nullable DateTime creationTime,
@Nullable Registrar registrar) {
ContactResource contactResource =
persistResource(makeContactResource(id, name, email, street, registrar));
if (creationTime != null) {
persistResource(makeHistoryEntry(
contactResource, HistoryEntry.Type.CONTACT_CREATE, null, "created", creationTime));