diff --git a/java/google/registry/rdap/BUILD b/java/google/registry/rdap/BUILD index 0499120a2..297fbaf68 100644 --- a/java/google/registry/rdap/BUILD +++ b/java/google/registry/rdap/BUILD @@ -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", diff --git a/java/google/registry/rdap/RdapActionBase.java b/java/google/registry/rdap/RdapActionBase.java index 0cf11abe0..4b345e7b8 100644 --- a/java/google/registry/rdap/RdapActionBase.java +++ b/java/google/registry/rdap/RdapActionBase.java @@ -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 getLoggedInClientId() { + if (!authResult.userAuthInfo().isPresent()) { + return Optional.absent(); + } + UserAuthInfo userAuthInfo = authResult.userAuthInfo().get(); + if (!sessionUtils.checkRegistrarConsoleLogin(request, userAuthInfo)) { + return Optional.absent(); + } + String clientId = sessionUtils.getRegistrarClientId(request); + Optional registrar = Registrar.loadByClientIdCached(clientId); + if (!registrar.isPresent()) { + return Optional.absent(); + } + return Optional.of(clientId); + } + void validateDomainName(String name) { try { Optional tld = findTldForName(InternetDomainName.from(name)); diff --git a/java/google/registry/rdap/RdapDomainAction.java b/java/google/registry/rdap/RdapDomainAction.java index e9fba3776..34f69da99 100644 --- a/java/google/registry/rdap/RdapDomainAction.java +++ b/java/google/registry/rdap/RdapDomainAction.java @@ -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()); } } diff --git a/java/google/registry/rdap/RdapDomainSearchAction.java b/java/google/registry/rdap/RdapDomainSearchAction.java index a9aa8bf54..4b24bd266 100644 --- a/java/google/registry/rdap/RdapDomainSearchAction.java +++ b/java/google/registry/rdap/RdapDomainSearchAction.java @@ -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 domains, boolean isTruncated, DateTime now) { OutputDataType outputDataType = (domains.size() > 1) ? OutputDataType.SUMMARY : OutputDataType.FULL; + Optional loggedInClientId = getLoggedInClientId(); ImmutableList.Builder> 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); } diff --git a/java/google/registry/rdap/RdapEntityAction.java b/java/google/registry/rdap/RdapEntityAction.java index d7998cd4e..4a04d5d2a 100644 --- a/java/google/registry/rdap/RdapEntityAction.java +++ b/java/google/registry/rdap/RdapEntityAction.java @@ -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); diff --git a/java/google/registry/rdap/RdapEntitySearchAction.java b/java/google/registry/rdap/RdapEntitySearchAction.java index 11b0ab66a..cdf52d76a 100644 --- a/java/google/registry/rdap/RdapEntitySearchAction.java +++ b/java/google/registry/rdap/RdapEntitySearchAction.java @@ -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 loggedInClientId = getLoggedInClientId(); List> 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()) { diff --git a/java/google/registry/rdap/RdapIcannStandardInformation.java b/java/google/registry/rdap/RdapIcannStandardInformation.java index 7fdddf5d1..6f0f99281 100644 --- a/java/google/registry/rdap/RdapIcannStandardInformation.java +++ b/java/google/registry/rdap/RdapIcannStandardInformation.java @@ -104,4 +104,24 @@ public class RdapIcannStandardInformation { /** Truncation notice as a singleton list, for easy use. */ static final ImmutableList> 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 DOMAIN_CONTACTS_HIDDEN_DATA_REMARK = + ImmutableMap. 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 CONTACT_PERSONAL_DATA_HIDDEN_DATA_REMARK = + ImmutableMap. 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"); } diff --git a/java/google/registry/rdap/RdapJsonFormatter.java b/java/google/registry/rdap/RdapJsonFormatter.java index 4ef16f502..b001a5e65 100644 --- a/java/google/registry/rdap/RdapJsonFormatter.java +++ b/java/google/registry/rdap/RdapJsonFormatter.java @@ -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 makeRdapJsonForDomain( DomainResource domainResource, @@ -451,7 +453,8 @@ public class RdapJsonFormatter { @Nullable String linkBase, @Nullable String whoisServer, DateTime now, - OutputDataType outputDataType) { + OutputDataType outputDataType, + Optional loggedInClientId) { // Start with the domain-level information. ImmutableMap.Builder 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,18 +476,43 @@ public class RdapJsonFormatter { if (outputDataType == OutputDataType.SUMMARY) { remarks = ImmutableList.of(RdapIcannStandardInformation.SUMMARY_DATA_REMARK); } else { - remarks = ImmutableList.of(); + remarks = displayContacts + ? ImmutableList.>of() + : ImmutableList.of(RdapIcannStandardInformation.DOMAIN_CONTACTS_HIDDEN_DATA_REMARK); ImmutableList 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, HostResource> loadedHosts = ofy().load().keys(domainResource.getNameservers()); - // And the registrant and other contacts. - Map, ContactResource> loadedContacts = - ofy().load().keys(domainResource.getReferencedContacts()); - // Nameservers + // Load the registrant and other contacts and add them to the data. + if (displayContacts) { + Map, ContactResource> loadedContacts = + ofy().load().keys(domainResource.getReferencedContacts()); + ImmutableList.Builder entitiesBuilder = new ImmutableList.Builder<>(); + for (DesignatedContact designatedContact : + FluentIterable.from(domainResource.getContacts()) + .append(DesignatedContact.create(Type.REGISTRANT, domainResource.getRegistrant())) + .toSortedList(DESIGNATED_CONTACT_ORDERING)) { + ContactResource loadedContact = loadedContacts.get(designatedContact.getContactKey()); + entitiesBuilder.add(makeRdapJsonForContact( + loadedContact, + false, + Optional.of(designatedContact.getType()), + linkBase, + null, + now, + outputDataType, + loggedInClientId)); + } + ImmutableList 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 nsBuilder = new ImmutableList.Builder<>(); for (HostResource hostResource : HOST_RESOURCE_ORDERING.immutableSortedCopy(loadedHosts.values())) { @@ -493,25 +523,6 @@ public class RdapJsonFormatter { if (!ns.isEmpty()) { jsonBuilder.put("nameservers", ns); } - // Contacts - ImmutableList.Builder entitiesBuilder = new ImmutableList.Builder<>(); - for (DesignatedContact designatedContact : FluentIterable.from(domainResource.getContacts()) - .append(DesignatedContact.create(Type.REGISTRANT, domainResource.getRegistrant())) - .toSortedList(DESIGNATED_CONTACT_ORDERING)) { - ContactResource loadedContact = loadedContacts.get(designatedContact.getContactKey()); - entitiesBuilder.add(makeRdapJsonForContact( - loadedContact, - false, - Optional.of(designatedContact.getType()), - linkBase, - null, - now, - outputDataType)); - } - ImmutableList entities = entitiesBuilder.build(); - if (!entities.isEmpty()) { - jsonBuilder.put("entities", entities); - } } 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 makeRdapJsonForContact( ContactResource contactResource, @@ -641,8 +654,11 @@ public class RdapJsonFormatter { @Nullable String linkBase, @Nullable String whoisServer, DateTime now, - OutputDataType outputDataType) { + OutputDataType outputDataType, + Optional loggedInClientId) { ImmutableMap.Builder jsonBuilder = new ImmutableMap.Builder<>(); + ImmutableList.Builder> remarksBuilder + = new ImmutableList.Builder<>(); jsonBuilder.put("objectClassName", "entity"); jsonBuilder.put("handle", contactResource.getRepoId()); jsonBuilder.put("status", makeStatusValueList( @@ -655,45 +671,48 @@ public class RdapJsonFormatter { } jsonBuilder.put("links", ImmutableList.of(makeLink("entity", contactResource.getRepoId(), linkBase))); - // Create the vCard. - ImmutableList.Builder vcardBuilder = new ImmutableList.Builder<>(); - vcardBuilder.add(VCARD_ENTRY_VERSION); - PostalInfo postalInfo = contactResource.getInternationalizedPostalInfo(); - if (postalInfo == null) { - postalInfo = contactResource.getLocalizedPostalInfo(); - } - if (postalInfo != null) { - if (postalInfo.getName() != null) { - vcardBuilder.add(ImmutableList.of("fn", ImmutableMap.of(), "text", postalInfo.getName())); + // If we are logged in as the owner of this contact, create the vCard. + if (loggedInClientId.isPresent() + && loggedInClientId.get().equals(contactResource.getCurrentSponsorClientId())) { + ImmutableList.Builder vcardBuilder = new ImmutableList.Builder<>(); + vcardBuilder.add(VCARD_ENTRY_VERSION); + PostalInfo postalInfo = contactResource.getInternationalizedPostalInfo(); + if (postalInfo == null) { + postalInfo = contactResource.getLocalizedPostalInfo(); } - if (postalInfo.getOrg() != null) { - vcardBuilder.add(ImmutableList.of("org", ImmutableMap.of(), "text", postalInfo.getOrg())); + if (postalInfo != null) { + if (postalInfo.getName() != null) { + vcardBuilder.add(ImmutableList.of("fn", ImmutableMap.of(), "text", postalInfo.getName())); + } + if (postalInfo.getOrg() != null) { + vcardBuilder.add(ImmutableList.of("org", ImmutableMap.of(), "text", postalInfo.getOrg())); + } + ImmutableList addressEntry = makeVCardAddressEntry(postalInfo.getAddress()); + if (addressEntry != null) { + vcardBuilder.add(addressEntry); + } } - ImmutableList addressEntry = makeVCardAddressEntry(postalInfo.getAddress()); - if (addressEntry != null) { - vcardBuilder.add(addressEntry); + ContactPhoneNumber voicePhoneNumber = contactResource.getVoiceNumber(); + if (voicePhoneNumber != null) { + vcardBuilder.add(makePhoneEntry(PHONE_TYPE_VOICE, makePhoneString(voicePhoneNumber))); } + ContactPhoneNumber faxPhoneNumber = contactResource.getFaxNumber(); + if (faxPhoneNumber != null) { + vcardBuilder.add(makePhoneEntry(PHONE_TYPE_FAX, makePhoneString(faxPhoneNumber))); + } + String emailAddress = contactResource.getEmailAddress(); + if (emailAddress != null) { + 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); } - ContactPhoneNumber voicePhoneNumber = contactResource.getVoiceNumber(); - if (voicePhoneNumber != null) { - vcardBuilder.add(makePhoneEntry(PHONE_TYPE_VOICE, makePhoneString(voicePhoneNumber))); - } - ContactPhoneNumber faxPhoneNumber = contactResource.getFaxNumber(); - if (faxPhoneNumber != null) { - vcardBuilder.add(makePhoneEntry(PHONE_TYPE_FAX, makePhoneString(faxPhoneNumber))); - } - String emailAddress = contactResource.getEmailAddress(); - if (emailAddress != null) { - vcardBuilder.add(ImmutableList.of("email", ImmutableMap.of(), "text", emailAddress)); - } - jsonBuilder.put("vcardArray", ImmutableList.of("vcard", vcardBuilder.build())); // 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> remarks; if (outputDataType == OutputDataType.SUMMARY) { - remarks = ImmutableList.of(RdapIcannStandardInformation.SUMMARY_DATA_REMARK); + remarksBuilder.add(RdapIcannStandardInformation.SUMMARY_DATA_REMARK); } else { - remarks = ImmutableList.of(); ImmutableList events = makeEvents(contactResource, now); if (!events.isEmpty()) { jsonBuilder.put("events", events); @@ -706,11 +725,14 @@ public class RdapJsonFormatter { addTopLevelEntries( jsonBuilder, BoilerplateType.ENTITY, - remarks, + remarksBuilder.build(), ImmutableList.>of(), linkBase); - } else if (!remarks.isEmpty()) { - jsonBuilder.put(REMARKS, remarks); + } else { + ImmutableList> remarks = remarksBuilder.build(); + if (!remarks.isEmpty()) { + jsonBuilder.put(REMARKS, remarks); + } } return jsonBuilder.build(); } diff --git a/java/google/registry/rdap/RdapUtils.java b/java/google/registry/rdap/RdapUtils.java index dd04512ee..54bc0c389 100644 --- a/java/google/registry/rdap/RdapUtils.java +++ b/java/google/registry/rdap/RdapUtils.java @@ -32,7 +32,8 @@ public final class RdapUtils { new Predicate() { @Override public boolean apply(Registrar registrar) { - return registrar.getIanaIdentifier() == ianaIdentifier; + Long registrarIanaIdentifier = registrar.getIanaIdentifier(); + return (registrarIanaIdentifier != null) && (registrarIanaIdentifier == ianaIdentifier); }}); } } diff --git a/javatests/google/registry/module/frontend/testdata/frontend_routing.txt b/javatests/google/registry/module/frontend/testdata/frontend_routing.txt index 37cf14f0e..6f34d77d3 100644 --- a/javatests/google/registry/module/frontend/testdata/frontend_routing.txt +++ b/javatests/google/registry/module/frontend/testdata/frontend_routing.txt @@ -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 diff --git a/javatests/google/registry/rdap/BUILD b/javatests/google/registry/rdap/BUILD index 1b2ff3680..f9713aebb 100644 --- a/javatests/google/registry/rdap/BUILD +++ b/javatests/google/registry/rdap/BUILD @@ -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", diff --git a/javatests/google/registry/rdap/RdapDomainActionTest.java b/javatests/google/registry/rdap/RdapDomainActionTest.java index 19ac0cc3d..ff5b35c4c 100644 --- a/javatests/google/registry/rdap/RdapDomainActionTest.java +++ b/javatests/google/registry/rdap/RdapDomainActionTest.java @@ -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