mirror of
https://github.com/google/nomulus.git
synced 2025-05-21 11:49:37 +02:00
Match logged-in GAE user ID with registrar POC user ID (#511)
* Match logged-in GAE user ID with registrar POC user ID The reasoning for this is thus: We wish to have the users log in using Google-managed addresses--this is so that we can manage enforcement of things like 2FA, as well as generic account management. However, we wish for the registry-lock confirmation emails to go to their standard non-Google email addresses--e.g. johndoe@theregistrar.com, rather than johndoe@registry.google. As a result, for registry lock, we will enable it on the johndoe@registry.google account, but we will alter the email address of the corresponding Registrar POC account to contain johndoe@theregistrar.com. By doing this, the user will still be logging in using the @registry.google account but we'll match to their actual contact email. * fix up comments and messages * Error if >1 matching contact * include email addresses * set default optional * fix tests
This commit is contained in:
parent
0545375eba
commit
d09fc7ee05
8 changed files with 148 additions and 68 deletions
|
@ -41,7 +41,6 @@ import google.registry.request.auth.Auth;
|
|||
import google.registry.request.auth.AuthResult;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||
import google.registry.request.auth.UserAuthInfo;
|
||||
import google.registry.schema.domain.RegistryLock;
|
||||
import google.registry.security.JsonResponseHelper;
|
||||
import java.util.Optional;
|
||||
|
@ -117,41 +116,61 @@ public final class RegistryLockGetAction implements JsonGetAction {
|
|||
}
|
||||
}
|
||||
|
||||
private ImmutableMap<String, ?> getLockedDomainsMap(String clientId)
|
||||
throws RegistrarAccessDeniedException {
|
||||
// Note: admins always have access to the locks page
|
||||
checkArgument(authResult.userAuthInfo().isPresent(), "User auth info must be present");
|
||||
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
||||
boolean isAdmin = registrarAccessor.isAdmin();
|
||||
Registrar registrar = getRegistrarAndVerifyLockAccess(clientId, isAdmin);
|
||||
User user = userAuthInfo.user();
|
||||
boolean isRegistryLockAllowed =
|
||||
isAdmin
|
||||
|| registrar.getContacts().stream()
|
||||
.filter(contact -> contact.getEmailAddress().equals(user.getEmail()))
|
||||
.findFirst()
|
||||
.map(RegistrarContact::isRegistryLockAllowed)
|
||||
.orElse(false);
|
||||
return ImmutableMap.of(
|
||||
LOCK_ENABLED_FOR_CONTACT_PARAM,
|
||||
isRegistryLockAllowed,
|
||||
EMAIL_PARAM,
|
||||
user.getEmail(),
|
||||
PARAM_CLIENT_ID,
|
||||
registrar.getClientId(),
|
||||
LOCKS_PARAM,
|
||||
getLockedDomains(clientId, isAdmin));
|
||||
static Optional<RegistrarContact> getContactMatchingLogin(User user, Registrar registrar) {
|
||||
ImmutableList<RegistrarContact> matchingContacts =
|
||||
registrar.getContacts().stream()
|
||||
.filter(contact -> contact.getGaeUserId().equals(user.getUserId()))
|
||||
.collect(toImmutableList());
|
||||
if (matchingContacts.size() > 1) {
|
||||
ImmutableList<String> matchingEmails =
|
||||
matchingContacts.stream()
|
||||
.map(RegistrarContact::getEmailAddress)
|
||||
.collect(toImmutableList());
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"User ID %s had multiple matching contacts with email addresses %s",
|
||||
user.getUserId(), matchingEmails));
|
||||
}
|
||||
return matchingContacts.stream().findFirst();
|
||||
}
|
||||
|
||||
private Registrar getRegistrarAndVerifyLockAccess(String clientId, boolean isAdmin)
|
||||
static Registrar getRegistrarAndVerifyLockAccess(
|
||||
AuthenticatedRegistrarAccessor registrarAccessor, String clientId, boolean isAdmin)
|
||||
throws RegistrarAccessDeniedException {
|
||||
Registrar registrar = registrarAccessor.getRegistrar(clientId);
|
||||
checkArgument(
|
||||
isAdmin || registrar.isRegistryLockAllowed(),
|
||||
"Registry lock not allowed for this registrar");
|
||||
"Registry lock not allowed for registrar %s",
|
||||
clientId);
|
||||
return registrar;
|
||||
}
|
||||
|
||||
private ImmutableMap<String, ?> getLockedDomainsMap(String clientId)
|
||||
throws RegistrarAccessDeniedException {
|
||||
// Note: admins always have access to the locks page
|
||||
checkArgument(authResult.userAuthInfo().isPresent(), "User auth info must be present");
|
||||
|
||||
boolean isAdmin = registrarAccessor.isAdmin();
|
||||
Registrar registrar = getRegistrarAndVerifyLockAccess(registrarAccessor, clientId, isAdmin);
|
||||
User user = authResult.userAuthInfo().get().user();
|
||||
|
||||
Optional<RegistrarContact> contactOptional = getContactMatchingLogin(user, registrar);
|
||||
boolean isRegistryLockAllowed =
|
||||
isAdmin || contactOptional.map(RegistrarContact::isRegistryLockAllowed).orElse(false);
|
||||
// Use the contact email if it's present, else use the login email
|
||||
String relevantEmail =
|
||||
contactOptional.map(RegistrarContact::getEmailAddress).orElse(user.getEmail());
|
||||
return ImmutableMap.of(
|
||||
LOCK_ENABLED_FOR_CONTACT_PARAM,
|
||||
isRegistryLockAllowed,
|
||||
EMAIL_PARAM,
|
||||
relevantEmail,
|
||||
PARAM_CLIENT_ID,
|
||||
registrar.getClientId(),
|
||||
LOCKS_PARAM,
|
||||
getLockedDomains(clientId, isAdmin));
|
||||
}
|
||||
|
||||
private ImmutableList<ImmutableMap<String, ?>> getLockedDomains(
|
||||
String clientId, boolean isAdmin) {
|
||||
return jpaTm()
|
||||
|
|
|
@ -20,8 +20,11 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
|
|||
import static google.registry.security.JsonResponseHelper.Status.ERROR;
|
||||
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
||||
import static google.registry.ui.server.registrar.RegistrarConsoleModule.PARAM_CLIENT_ID;
|
||||
import static google.registry.ui.server.registrar.RegistryLockGetAction.getContactMatchingLogin;
|
||||
import static google.registry.ui.server.registrar.RegistryLockGetAction.getRegistrarAndVerifyLockAccess;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -124,11 +127,7 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
|||
.userAuthInfo()
|
||||
.orElseThrow(() -> new ForbiddenException("User is not logged in"));
|
||||
|
||||
boolean isAdmin = userAuthInfo.isUserAdmin();
|
||||
String userEmail = userAuthInfo.user().getEmail();
|
||||
if (!isAdmin) {
|
||||
verifyRegistryLockPassword(postInput, userEmail);
|
||||
}
|
||||
String userEmail = verifyPasswordAndGetEmail(userAuthInfo, postInput);
|
||||
jpaTm()
|
||||
.transact(
|
||||
() -> {
|
||||
|
@ -138,9 +137,11 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
|||
postInput.fullyQualifiedDomainName,
|
||||
postInput.clientId,
|
||||
userEmail,
|
||||
isAdmin)
|
||||
registrarAccessor.isAdmin())
|
||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||
postInput.fullyQualifiedDomainName, postInput.clientId, isAdmin);
|
||||
postInput.fullyQualifiedDomainName,
|
||||
postInput.clientId,
|
||||
registrarAccessor.isAdmin());
|
||||
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
|
||||
});
|
||||
String action = postInput.isLock ? "lock" : "unlock";
|
||||
|
@ -180,25 +181,28 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
|||
}
|
||||
}
|
||||
|
||||
private void verifyRegistryLockPassword(RegistryLockPostInput postInput, String userEmail)
|
||||
private String verifyPasswordAndGetEmail(
|
||||
UserAuthInfo userAuthInfo, RegistryLockPostInput postInput)
|
||||
throws RegistrarAccessDeniedException {
|
||||
// Verify that the user can access the registrar and that the user has
|
||||
// registry lock enabled and provided a correct password
|
||||
Registrar registrar = registrarAccessor.getRegistrar(postInput.clientId);
|
||||
checkArgument(
|
||||
registrar.isRegistryLockAllowed(), "Registry lock not allowed for this registrar");
|
||||
checkArgument(!Strings.isNullOrEmpty(postInput.password), "Missing key for password");
|
||||
User user = userAuthInfo.user();
|
||||
if (registrarAccessor.isAdmin()) {
|
||||
return user.getEmail();
|
||||
}
|
||||
// Verify that the user can access the registrar, that the user has
|
||||
// registry lock enabled, and that the user providjed a correct password
|
||||
Registrar registrar =
|
||||
getRegistrarAndVerifyLockAccess(registrarAccessor, postInput.clientId, false);
|
||||
RegistrarContact registrarContact =
|
||||
registrar.getContacts().stream()
|
||||
.filter(contact -> contact.getEmailAddress().equals(userEmail))
|
||||
.findFirst()
|
||||
getContactMatchingLogin(user, registrar)
|
||||
.orElseThrow(
|
||||
() ->
|
||||
new IllegalArgumentException(
|
||||
String.format("Unknown user email %s", userEmail)));
|
||||
String.format(
|
||||
"Cannot match user %s to registrar contact", user.getUserId())));
|
||||
checkArgument(
|
||||
registrarContact.verifyRegistryLockPassword(postInput.password),
|
||||
"Incorrect registry lock password for contact");
|
||||
return registrarContact.getEmailAddress();
|
||||
}
|
||||
|
||||
/** Value class that represents the expected input body from the UI request. */
|
||||
|
|
|
@ -249,7 +249,7 @@ public final class AppEngineRule extends ExternalResource {
|
|||
.setEmailAddress("Marla.Singer@crr.com")
|
||||
.setPhoneNumber("+1.2128675309")
|
||||
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
|
||||
.setGaeUserId(THE_REGISTRAR_GAE_USER_ID)
|
||||
.setGaeUserId("12345")
|
||||
.setAllowedToSetRegistryLockPassword(true)
|
||||
.setRegistryLockPassword("hi")
|
||||
.build();
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.gson.Gson;
|
||||
import google.registry.model.registrar.RegistrarContact;
|
||||
import google.registry.request.Action.Method;
|
||||
import google.registry.request.auth.AuthLevel;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
|
@ -67,14 +68,15 @@ public final class RegistryLockGetActionTest {
|
|||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
private final FakeResponse response = new FakeResponse();
|
||||
private final User user = new User("Marla.Singer@crr.com", "gmail.com", "12345");
|
||||
|
||||
private User user;
|
||||
private AuthResult authResult;
|
||||
private AuthenticatedRegistrarAccessor accessor;
|
||||
private RegistryLockGetAction action;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
user = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
|
||||
fakeClock.setTo(DateTime.parse("2000-06-08T22:00:00.0Z"));
|
||||
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
|
||||
accessor =
|
||||
|
@ -309,6 +311,29 @@ public final class RegistryLockGetActionTest {
|
|||
ImmutableList.of())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_linkedToContactEmail() {
|
||||
// Even though the user is some.email@gmail.com the contact is still Marla Singer
|
||||
user = new User("some.email@gmail.com", "gmail.com", user.getUserId());
|
||||
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
|
||||
action =
|
||||
new RegistryLockGetAction(
|
||||
Method.GET, response, accessor, authResult, Optional.of("TheRegistrar"));
|
||||
action.run();
|
||||
assertThat(GSON.fromJson(response.getPayload(), Map.class).get("results"))
|
||||
.isEqualTo(
|
||||
ImmutableList.of(
|
||||
ImmutableMap.of(
|
||||
"lockEnabledForContact",
|
||||
true,
|
||||
"email",
|
||||
"Marla.Singer@crr.com",
|
||||
"clientId",
|
||||
"TheRegistrar",
|
||||
"locks",
|
||||
ImmutableList.of())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_lockNotAllowedForRegistrar() {
|
||||
// The UI shouldn't be making requests where lock isn't enabled for this registrar
|
||||
|
@ -337,4 +362,9 @@ public final class RegistryLockGetActionTest {
|
|||
action.run();
|
||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
||||
}
|
||||
|
||||
static User userFromRegistrarContact(RegistrarContact registrarContact) {
|
||||
return new User(
|
||||
registrarContact.getEmailAddress(), "gmail.com", registrarContact.getGaeUserId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import static google.registry.testing.DatastoreHelper.persistResource;
|
|||
import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode;
|
||||
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
||||
import static google.registry.ui.server.registrar.RegistryLockGetActionTest.userFromRegistrarContact;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
|
@ -78,11 +79,8 @@ public final class RegistryLockPostActionTest {
|
|||
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
private final User userWithoutPermission =
|
||||
new User("johndoe@theregistrar.com", "gmail.com", "31337");
|
||||
// Marla Singer has registry lock auth permissions
|
||||
private final User userWithLockPermission =
|
||||
new User("Marla.Singer@crr.com", "gmail.com", "31337");
|
||||
private User userWithoutPermission;
|
||||
private User userWithLockPermission;
|
||||
|
||||
private InternetAddress outgoingAddress;
|
||||
private DomainBase domain;
|
||||
|
@ -93,6 +91,8 @@ public final class RegistryLockPostActionTest {
|
|||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
userWithLockPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
|
||||
userWithoutPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact2());
|
||||
createTld("tld");
|
||||
domain = persistResource(newDomainBase("example.tld"));
|
||||
outgoingAddress = new InternetAddress("domain-registry@example.com");
|
||||
|
@ -133,6 +133,18 @@ public final class RegistryLockPostActionTest {
|
|||
assertSuccess(response, "unlock", "johndoe@theregistrar.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccess_linkedToContactEmail() throws Exception {
|
||||
// Even though the user is some.email@gmail.com the contact is still Marla Singer
|
||||
userWithLockPermission =
|
||||
new User("some.email@gmail.com", "gmail.com", userWithLockPermission.getUserId());
|
||||
action =
|
||||
createAction(
|
||||
AuthResult.create(AuthLevel.USER, UserAuthInfo.create(userWithLockPermission, false)));
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertSuccess(response, "lock", "Marla.Singer@crr.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFailure_unlock_noLock() {
|
||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||
|
@ -233,7 +245,7 @@ public final class RegistryLockPostActionTest {
|
|||
persistResource(
|
||||
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
||||
assertFailureWithMessage(response, "Registry lock not allowed for this registrar");
|
||||
assertFailureWithMessage(response, "Registry lock not allowed for registrar TheRegistrar");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -244,7 +256,7 @@ public final class RegistryLockPostActionTest {
|
|||
"clientId", "TheRegistrar",
|
||||
"fullyQualifiedDomainName", "example.tld",
|
||||
"isLock", true));
|
||||
assertFailureWithMessage(response, "Missing key for password");
|
||||
assertFailureWithMessage(response, "Incorrect registry lock password for contact");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -386,9 +398,10 @@ public final class RegistryLockPostActionTest {
|
|||
}
|
||||
|
||||
private RegistryLockPostAction createAction(AuthResult authResult) {
|
||||
Role role = authResult.userAuthInfo().get().isUserAdmin() ? Role.ADMIN : Role.OWNER;
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
AuthenticatedRegistrarAccessor.createForTesting(
|
||||
ImmutableSetMultimap.of("TheRegistrar", Role.OWNER, "NewRegistrar", Role.OWNER));
|
||||
ImmutableSetMultimap.of("TheRegistrar", role, "NewRegistrar", role));
|
||||
JsonActionRunner jsonActionRunner =
|
||||
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
|
||||
DomainLockUtils domainLockUtils =
|
||||
|
|
|
@ -60,7 +60,8 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
|||
route("/registry-lock-verify", FrontendServlet.class))
|
||||
.setFilters(ObjectifyFilter.class, OfyFilter.class)
|
||||
.setFixtures(BASIC)
|
||||
.setEmail("Marla.Singer@crr.com")
|
||||
.setEmail("Marla.Singer@crr.com") // from AppEngineRule.makeRegistrarContact3
|
||||
.setGaeUserId("12345") // from AppEngineRule.makeRegistrarContact3
|
||||
.build();
|
||||
|
||||
@Test
|
||||
|
@ -452,11 +453,12 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
|||
createTld("tld");
|
||||
// expired unlock request
|
||||
DomainBase expiredUnlockRequestDomain = persistActiveDomain("expiredunlock.tld");
|
||||
saveRegistryLock(createRegistryLock(expiredUnlockRequestDomain)
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
|
||||
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
|
||||
.build());
|
||||
saveRegistryLock(
|
||||
createRegistryLock(expiredUnlockRequestDomain)
|
||||
.asBuilder()
|
||||
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
|
||||
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
|
||||
.build());
|
||||
DomainBase domain = persistActiveDomain("example.tld");
|
||||
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
|
||||
DomainBase otherDomain = persistActiveDomain("otherexample.tld");
|
||||
|
|
|
@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static google.registry.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
|
||||
import static google.registry.util.NetworkUtils.getExternalAddressOfLocalSystem;
|
||||
import static google.registry.util.NetworkUtils.pickUnusedPort;
|
||||
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -32,6 +33,7 @@ import google.registry.testing.UserInfo;
|
|||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
@ -66,7 +68,8 @@ public final class TestServerRule extends ExternalResource {
|
|||
ImmutableList<Route> routes,
|
||||
ImmutableList<Class<? extends Filter>> filters,
|
||||
ImmutableList<Fixture> fixtures,
|
||||
String email) {
|
||||
String email,
|
||||
Optional<String> gaeUserId) {
|
||||
this.runfiles = runfiles;
|
||||
this.routes = routes;
|
||||
this.filters = filters;
|
||||
|
@ -79,7 +82,8 @@ public final class TestServerRule extends ExternalResource {
|
|||
.withLocalModules()
|
||||
.withUrlFetch()
|
||||
.withTaskQueue()
|
||||
.withUserService(UserInfo.createAdmin(email, THE_REGISTRAR_GAE_USER_ID))
|
||||
.withUserService(
|
||||
UserInfo.createAdmin(email, gaeUserId.orElse(THE_REGISTRAR_GAE_USER_ID)))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -149,8 +153,8 @@ public final class TestServerRule extends ExternalResource {
|
|||
/**
|
||||
* Runs arbitrary code inside server event loop thread.
|
||||
*
|
||||
* <p>You should use this method when you want to do things like change Datastore, because the
|
||||
* App Engine testing environment is thread-local.
|
||||
* <p>You should use this method when you want to do things like change Datastore, because the App
|
||||
* Engine testing environment is thread-local.
|
||||
*/
|
||||
public <T> T runInAppEngineEnvironment(Callable<T> callback) throws Throwable {
|
||||
FutureTask<T> job = new FutureTask<>(callback);
|
||||
|
@ -211,7 +215,6 @@ public final class TestServerRule extends ExternalResource {
|
|||
*
|
||||
* <p>This builder has three required fields: {@link #setRunfiles}, {@link #setRoutes}, and {@link
|
||||
* #setFilters}.
|
||||
*
|
||||
*/
|
||||
public static final class Builder {
|
||||
private ImmutableMap<String, Path> runfiles;
|
||||
|
@ -219,6 +222,7 @@ public final class TestServerRule extends ExternalResource {
|
|||
ImmutableList<Class<? extends Filter>> filters;
|
||||
private ImmutableList<Fixture> fixtures = ImmutableList.of();
|
||||
private String email;
|
||||
private Optional<String> gaeUserId = Optional.empty();
|
||||
|
||||
/** Sets the directories containing the static files for {@link TestServer}. */
|
||||
public Builder setRunfiles(ImmutableMap<String, Path> runfiles) {
|
||||
|
@ -256,6 +260,13 @@ public final class TestServerRule extends ExternalResource {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Optionally, sets the GAE user ID for the logged in user. */
|
||||
public Builder setGaeUserId(String gaeUserId) {
|
||||
this.gaeUserId =
|
||||
Optional.of(checkArgumentNotNull(gaeUserId, "Must specify a non-null GAE user ID"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns a new {@link TestServerRule} instance. */
|
||||
public TestServerRule build() {
|
||||
return new TestServerRule(
|
||||
|
@ -263,7 +274,8 @@ public final class TestServerRule extends ExternalResource {
|
|||
checkNotNull(this.routes),
|
||||
checkNotNull(this.filters),
|
||||
checkNotNull(this.fixtures),
|
||||
checkNotNull(this.email));
|
||||
checkNotNull(this.email),
|
||||
this.gaeUserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ contacts:
|
|||
ADDED:
|
||||
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Extra Terrestrial, emailAddress=etphonehome@example.com, phoneNumber=+1.2345678901, faxNumber=null, types=[ADMIN, BILLING, TECH, WHOIS], gaeUserId=null, visibleInWhoisAsAdmin=true, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
|
||||
REMOVED:
|
||||
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Marla Singer, emailAddress=Marla.Singer@crr.com, phoneNumber=+1.2128675309, faxNumber=null, types=[TECH], gaeUserId=31337, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
|
||||
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Marla Singer, emailAddress=Marla.Singer@crr.com, phoneNumber=+1.2128675309, faxNumber=null, types=[TECH], gaeUserId=12345, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
|
||||
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=John Doe, emailAddress=johndoe@theregistrar.com, phoneNumber=+1.1234567890, faxNumber=null, types=[ADMIN], gaeUserId=31337, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false},
|
||||
{parent=Key<?>(EntityGroupRoot("cross-tld")/Registrar("TheRegistrar")), name=Jian-Yang, emailAddress=jyang@bachman.accelerator, phoneNumber=+1.1234567890, faxNumber=null, types=[TECH], gaeUserId=null, visibleInWhoisAsAdmin=false, visibleInWhoisAsTech=false, visibleInDomainWhoisAsAbuse=false, allowedToSetRegistryLockPassword=false}
|
||||
FINAL CONTENTS:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue