mirror of
https://github.com/google/nomulus.git
synced 2025-05-21 19:59:34 +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.AuthResult;
|
||||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor;
|
||||||
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
|
||||||
import google.registry.request.auth.UserAuthInfo;
|
|
||||||
import google.registry.schema.domain.RegistryLock;
|
import google.registry.schema.domain.RegistryLock;
|
||||||
import google.registry.security.JsonResponseHelper;
|
import google.registry.security.JsonResponseHelper;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -117,41 +116,61 @@ public final class RegistryLockGetAction implements JsonGetAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImmutableMap<String, ?> getLockedDomainsMap(String clientId)
|
static Optional<RegistrarContact> getContactMatchingLogin(User user, Registrar registrar) {
|
||||||
throws RegistrarAccessDeniedException {
|
ImmutableList<RegistrarContact> matchingContacts =
|
||||||
// Note: admins always have access to the locks page
|
registrar.getContacts().stream()
|
||||||
checkArgument(authResult.userAuthInfo().isPresent(), "User auth info must be present");
|
.filter(contact -> contact.getGaeUserId().equals(user.getUserId()))
|
||||||
UserAuthInfo userAuthInfo = authResult.userAuthInfo().get();
|
.collect(toImmutableList());
|
||||||
boolean isAdmin = registrarAccessor.isAdmin();
|
if (matchingContacts.size() > 1) {
|
||||||
Registrar registrar = getRegistrarAndVerifyLockAccess(clientId, isAdmin);
|
ImmutableList<String> matchingEmails =
|
||||||
User user = userAuthInfo.user();
|
matchingContacts.stream()
|
||||||
boolean isRegistryLockAllowed =
|
.map(RegistrarContact::getEmailAddress)
|
||||||
isAdmin
|
.collect(toImmutableList());
|
||||||
|| registrar.getContacts().stream()
|
throw new IllegalArgumentException(
|
||||||
.filter(contact -> contact.getEmailAddress().equals(user.getEmail()))
|
String.format(
|
||||||
.findFirst()
|
"User ID %s had multiple matching contacts with email addresses %s",
|
||||||
.map(RegistrarContact::isRegistryLockAllowed)
|
user.getUserId(), matchingEmails));
|
||||||
.orElse(false);
|
}
|
||||||
return ImmutableMap.of(
|
return matchingContacts.stream().findFirst();
|
||||||
LOCK_ENABLED_FOR_CONTACT_PARAM,
|
|
||||||
isRegistryLockAllowed,
|
|
||||||
EMAIL_PARAM,
|
|
||||||
user.getEmail(),
|
|
||||||
PARAM_CLIENT_ID,
|
|
||||||
registrar.getClientId(),
|
|
||||||
LOCKS_PARAM,
|
|
||||||
getLockedDomains(clientId, isAdmin));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Registrar getRegistrarAndVerifyLockAccess(String clientId, boolean isAdmin)
|
static Registrar getRegistrarAndVerifyLockAccess(
|
||||||
|
AuthenticatedRegistrarAccessor registrarAccessor, String clientId, boolean isAdmin)
|
||||||
throws RegistrarAccessDeniedException {
|
throws RegistrarAccessDeniedException {
|
||||||
Registrar registrar = registrarAccessor.getRegistrar(clientId);
|
Registrar registrar = registrarAccessor.getRegistrar(clientId);
|
||||||
checkArgument(
|
checkArgument(
|
||||||
isAdmin || registrar.isRegistryLockAllowed(),
|
isAdmin || registrar.isRegistryLockAllowed(),
|
||||||
"Registry lock not allowed for this registrar");
|
"Registry lock not allowed for registrar %s",
|
||||||
|
clientId);
|
||||||
return registrar;
|
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(
|
private ImmutableList<ImmutableMap<String, ?>> getLockedDomains(
|
||||||
String clientId, boolean isAdmin) {
|
String clientId, boolean isAdmin) {
|
||||||
return jpaTm()
|
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.ERROR;
|
||||||
import static google.registry.security.JsonResponseHelper.Status.SUCCESS;
|
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.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 static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
|
||||||
|
|
||||||
|
import com.google.appengine.api.users.User;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -124,11 +127,7 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
||||||
.userAuthInfo()
|
.userAuthInfo()
|
||||||
.orElseThrow(() -> new ForbiddenException("User is not logged in"));
|
.orElseThrow(() -> new ForbiddenException("User is not logged in"));
|
||||||
|
|
||||||
boolean isAdmin = userAuthInfo.isUserAdmin();
|
String userEmail = verifyPasswordAndGetEmail(userAuthInfo, postInput);
|
||||||
String userEmail = userAuthInfo.user().getEmail();
|
|
||||||
if (!isAdmin) {
|
|
||||||
verifyRegistryLockPassword(postInput, userEmail);
|
|
||||||
}
|
|
||||||
jpaTm()
|
jpaTm()
|
||||||
.transact(
|
.transact(
|
||||||
() -> {
|
() -> {
|
||||||
|
@ -138,9 +137,11 @@ public class RegistryLockPostAction implements Runnable, JsonActionRunner.JsonAc
|
||||||
postInput.fullyQualifiedDomainName,
|
postInput.fullyQualifiedDomainName,
|
||||||
postInput.clientId,
|
postInput.clientId,
|
||||||
userEmail,
|
userEmail,
|
||||||
isAdmin)
|
registrarAccessor.isAdmin())
|
||||||
: domainLockUtils.saveNewRegistryUnlockRequest(
|
: domainLockUtils.saveNewRegistryUnlockRequest(
|
||||||
postInput.fullyQualifiedDomainName, postInput.clientId, isAdmin);
|
postInput.fullyQualifiedDomainName,
|
||||||
|
postInput.clientId,
|
||||||
|
registrarAccessor.isAdmin());
|
||||||
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
|
sendVerificationEmail(registryLock, userEmail, postInput.isLock);
|
||||||
});
|
});
|
||||||
String action = postInput.isLock ? "lock" : "unlock";
|
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 {
|
throws RegistrarAccessDeniedException {
|
||||||
// Verify that the user can access the registrar and that the user has
|
User user = userAuthInfo.user();
|
||||||
// registry lock enabled and provided a correct password
|
if (registrarAccessor.isAdmin()) {
|
||||||
Registrar registrar = registrarAccessor.getRegistrar(postInput.clientId);
|
return user.getEmail();
|
||||||
checkArgument(
|
}
|
||||||
registrar.isRegistryLockAllowed(), "Registry lock not allowed for this registrar");
|
// Verify that the user can access the registrar, that the user has
|
||||||
checkArgument(!Strings.isNullOrEmpty(postInput.password), "Missing key for password");
|
// registry lock enabled, and that the user providjed a correct password
|
||||||
|
Registrar registrar =
|
||||||
|
getRegistrarAndVerifyLockAccess(registrarAccessor, postInput.clientId, false);
|
||||||
RegistrarContact registrarContact =
|
RegistrarContact registrarContact =
|
||||||
registrar.getContacts().stream()
|
getContactMatchingLogin(user, registrar)
|
||||||
.filter(contact -> contact.getEmailAddress().equals(userEmail))
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow(
|
.orElseThrow(
|
||||||
() ->
|
() ->
|
||||||
new IllegalArgumentException(
|
new IllegalArgumentException(
|
||||||
String.format("Unknown user email %s", userEmail)));
|
String.format(
|
||||||
|
"Cannot match user %s to registrar contact", user.getUserId())));
|
||||||
checkArgument(
|
checkArgument(
|
||||||
registrarContact.verifyRegistryLockPassword(postInput.password),
|
registrarContact.verifyRegistryLockPassword(postInput.password),
|
||||||
"Incorrect registry lock password for contact");
|
"Incorrect registry lock password for contact");
|
||||||
|
return registrarContact.getEmailAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Value class that represents the expected input body from the UI request. */
|
/** 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")
|
.setEmailAddress("Marla.Singer@crr.com")
|
||||||
.setPhoneNumber("+1.2128675309")
|
.setPhoneNumber("+1.2128675309")
|
||||||
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
|
.setTypes(ImmutableSet.of(RegistrarContact.Type.TECH))
|
||||||
.setGaeUserId(THE_REGISTRAR_GAE_USER_ID)
|
.setGaeUserId("12345")
|
||||||
.setAllowedToSetRegistryLockPassword(true)
|
.setAllowedToSetRegistryLockPassword(true)
|
||||||
.setRegistryLockPassword("hi")
|
.setRegistryLockPassword("hi")
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import google.registry.model.registrar.RegistrarContact;
|
||||||
import google.registry.request.Action.Method;
|
import google.registry.request.Action.Method;
|
||||||
import google.registry.request.auth.AuthLevel;
|
import google.registry.request.auth.AuthLevel;
|
||||||
import google.registry.request.auth.AuthResult;
|
import google.registry.request.auth.AuthResult;
|
||||||
|
@ -67,14 +68,15 @@ public final class RegistryLockGetActionTest {
|
||||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||||
|
|
||||||
private final FakeResponse response = new FakeResponse();
|
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 AuthResult authResult;
|
||||||
private AuthenticatedRegistrarAccessor accessor;
|
private AuthenticatedRegistrarAccessor accessor;
|
||||||
private RegistryLockGetAction action;
|
private RegistryLockGetAction action;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
user = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
|
||||||
fakeClock.setTo(DateTime.parse("2000-06-08T22:00:00.0Z"));
|
fakeClock.setTo(DateTime.parse("2000-06-08T22:00:00.0Z"));
|
||||||
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
|
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
|
||||||
accessor =
|
accessor =
|
||||||
|
@ -309,6 +311,29 @@ public final class RegistryLockGetActionTest {
|
||||||
ImmutableList.of())));
|
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
|
@Test
|
||||||
public void testFailure_lockNotAllowedForRegistrar() {
|
public void testFailure_lockNotAllowedForRegistrar() {
|
||||||
// The UI shouldn't be making requests where lock isn't enabled for this registrar
|
// 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();
|
action.run();
|
||||||
assertThat(response.getStatus()).isEqualTo(SC_FORBIDDEN);
|
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.getRegistryLockByVerificationCode;
|
||||||
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
import static google.registry.testing.SqlHelper.saveRegistryLock;
|
||||||
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
|
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.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
|
@ -78,11 +79,8 @@ public final class RegistryLockPostActionTest {
|
||||||
|
|
||||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||||
|
|
||||||
private final User userWithoutPermission =
|
private User userWithoutPermission;
|
||||||
new User("johndoe@theregistrar.com", "gmail.com", "31337");
|
private User userWithLockPermission;
|
||||||
// Marla Singer has registry lock auth permissions
|
|
||||||
private final User userWithLockPermission =
|
|
||||||
new User("Marla.Singer@crr.com", "gmail.com", "31337");
|
|
||||||
|
|
||||||
private InternetAddress outgoingAddress;
|
private InternetAddress outgoingAddress;
|
||||||
private DomainBase domain;
|
private DomainBase domain;
|
||||||
|
@ -93,6 +91,8 @@ public final class RegistryLockPostActionTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
|
userWithLockPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact3());
|
||||||
|
userWithoutPermission = userFromRegistrarContact(AppEngineRule.makeRegistrarContact2());
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
domain = persistResource(newDomainBase("example.tld"));
|
domain = persistResource(newDomainBase("example.tld"));
|
||||||
outgoingAddress = new InternetAddress("domain-registry@example.com");
|
outgoingAddress = new InternetAddress("domain-registry@example.com");
|
||||||
|
@ -133,6 +133,18 @@ public final class RegistryLockPostActionTest {
|
||||||
assertSuccess(response, "unlock", "johndoe@theregistrar.com");
|
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
|
@Test
|
||||||
public void testFailure_unlock_noLock() {
|
public void testFailure_unlock_noLock() {
|
||||||
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
persistResource(domain.asBuilder().setStatusValues(REGISTRY_LOCK_STATUSES).build());
|
||||||
|
@ -233,7 +245,7 @@ public final class RegistryLockPostActionTest {
|
||||||
persistResource(
|
persistResource(
|
||||||
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
loadRegistrar("TheRegistrar").asBuilder().setRegistryLockAllowed(false).build());
|
||||||
Map<String, ?> response = action.handleJsonRequest(lockRequest());
|
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
|
@Test
|
||||||
|
@ -244,7 +256,7 @@ public final class RegistryLockPostActionTest {
|
||||||
"clientId", "TheRegistrar",
|
"clientId", "TheRegistrar",
|
||||||
"fullyQualifiedDomainName", "example.tld",
|
"fullyQualifiedDomainName", "example.tld",
|
||||||
"isLock", true));
|
"isLock", true));
|
||||||
assertFailureWithMessage(response, "Missing key for password");
|
assertFailureWithMessage(response, "Incorrect registry lock password for contact");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -386,9 +398,10 @@ public final class RegistryLockPostActionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RegistryLockPostAction createAction(AuthResult authResult) {
|
private RegistryLockPostAction createAction(AuthResult authResult) {
|
||||||
|
Role role = authResult.userAuthInfo().get().isUserAdmin() ? Role.ADMIN : Role.OWNER;
|
||||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||||
AuthenticatedRegistrarAccessor.createForTesting(
|
AuthenticatedRegistrarAccessor.createForTesting(
|
||||||
ImmutableSetMultimap.of("TheRegistrar", Role.OWNER, "NewRegistrar", Role.OWNER));
|
ImmutableSetMultimap.of("TheRegistrar", role, "NewRegistrar", role));
|
||||||
JsonActionRunner jsonActionRunner =
|
JsonActionRunner jsonActionRunner =
|
||||||
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
|
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
|
||||||
DomainLockUtils domainLockUtils =
|
DomainLockUtils domainLockUtils =
|
||||||
|
|
|
@ -60,7 +60,8 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||||
route("/registry-lock-verify", FrontendServlet.class))
|
route("/registry-lock-verify", FrontendServlet.class))
|
||||||
.setFilters(ObjectifyFilter.class, OfyFilter.class)
|
.setFilters(ObjectifyFilter.class, OfyFilter.class)
|
||||||
.setFixtures(BASIC)
|
.setFixtures(BASIC)
|
||||||
.setEmail("Marla.Singer@crr.com")
|
.setEmail("Marla.Singer@crr.com") // from AppEngineRule.makeRegistrarContact3
|
||||||
|
.setGaeUserId("12345") // from AppEngineRule.makeRegistrarContact3
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -452,11 +453,12 @@ public class RegistrarConsoleScreenshotTest extends WebDriverTestCase {
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
// expired unlock request
|
// expired unlock request
|
||||||
DomainBase expiredUnlockRequestDomain = persistActiveDomain("expiredunlock.tld");
|
DomainBase expiredUnlockRequestDomain = persistActiveDomain("expiredunlock.tld");
|
||||||
saveRegistryLock(createRegistryLock(expiredUnlockRequestDomain)
|
saveRegistryLock(
|
||||||
.asBuilder()
|
createRegistryLock(expiredUnlockRequestDomain)
|
||||||
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
|
.asBuilder()
|
||||||
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
|
.setLockCompletionTimestamp(START_OF_TIME.minusDays(1))
|
||||||
.build());
|
.setUnlockRequestTimestamp(START_OF_TIME.minusDays(1))
|
||||||
|
.build());
|
||||||
DomainBase domain = persistActiveDomain("example.tld");
|
DomainBase domain = persistActiveDomain("example.tld");
|
||||||
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
|
saveRegistryLock(createRegistryLock(domain).asBuilder().isSuperuser(true).build());
|
||||||
DomainBase otherDomain = persistActiveDomain("otherexample.tld");
|
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.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
|
||||||
import static google.registry.util.NetworkUtils.getExternalAddressOfLocalSystem;
|
import static google.registry.util.NetworkUtils.getExternalAddressOfLocalSystem;
|
||||||
import static google.registry.util.NetworkUtils.pickUnusedPort;
|
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.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -32,6 +33,7 @@ import google.registry.testing.UserInfo;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.FutureTask;
|
import java.util.concurrent.FutureTask;
|
||||||
|
@ -66,7 +68,8 @@ public final class TestServerRule extends ExternalResource {
|
||||||
ImmutableList<Route> routes,
|
ImmutableList<Route> routes,
|
||||||
ImmutableList<Class<? extends Filter>> filters,
|
ImmutableList<Class<? extends Filter>> filters,
|
||||||
ImmutableList<Fixture> fixtures,
|
ImmutableList<Fixture> fixtures,
|
||||||
String email) {
|
String email,
|
||||||
|
Optional<String> gaeUserId) {
|
||||||
this.runfiles = runfiles;
|
this.runfiles = runfiles;
|
||||||
this.routes = routes;
|
this.routes = routes;
|
||||||
this.filters = filters;
|
this.filters = filters;
|
||||||
|
@ -79,7 +82,8 @@ public final class TestServerRule extends ExternalResource {
|
||||||
.withLocalModules()
|
.withLocalModules()
|
||||||
.withUrlFetch()
|
.withUrlFetch()
|
||||||
.withTaskQueue()
|
.withTaskQueue()
|
||||||
.withUserService(UserInfo.createAdmin(email, THE_REGISTRAR_GAE_USER_ID))
|
.withUserService(
|
||||||
|
UserInfo.createAdmin(email, gaeUserId.orElse(THE_REGISTRAR_GAE_USER_ID)))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,8 +153,8 @@ public final class TestServerRule extends ExternalResource {
|
||||||
/**
|
/**
|
||||||
* Runs arbitrary code inside server event loop thread.
|
* 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
|
* <p>You should use this method when you want to do things like change Datastore, because the App
|
||||||
* App Engine testing environment is thread-local.
|
* Engine testing environment is thread-local.
|
||||||
*/
|
*/
|
||||||
public <T> T runInAppEngineEnvironment(Callable<T> callback) throws Throwable {
|
public <T> T runInAppEngineEnvironment(Callable<T> callback) throws Throwable {
|
||||||
FutureTask<T> job = new FutureTask<>(callback);
|
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
|
* <p>This builder has three required fields: {@link #setRunfiles}, {@link #setRoutes}, and {@link
|
||||||
* #setFilters}.
|
* #setFilters}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
private ImmutableMap<String, Path> runfiles;
|
private ImmutableMap<String, Path> runfiles;
|
||||||
|
@ -219,6 +222,7 @@ public final class TestServerRule extends ExternalResource {
|
||||||
ImmutableList<Class<? extends Filter>> filters;
|
ImmutableList<Class<? extends Filter>> filters;
|
||||||
private ImmutableList<Fixture> fixtures = ImmutableList.of();
|
private ImmutableList<Fixture> fixtures = ImmutableList.of();
|
||||||
private String email;
|
private String email;
|
||||||
|
private Optional<String> gaeUserId = Optional.empty();
|
||||||
|
|
||||||
/** Sets the directories containing the static files for {@link TestServer}. */
|
/** Sets the directories containing the static files for {@link TestServer}. */
|
||||||
public Builder setRunfiles(ImmutableMap<String, Path> runfiles) {
|
public Builder setRunfiles(ImmutableMap<String, Path> runfiles) {
|
||||||
|
@ -256,6 +260,13 @@ public final class TestServerRule extends ExternalResource {
|
||||||
return this;
|
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. */
|
/** Returns a new {@link TestServerRule} instance. */
|
||||||
public TestServerRule build() {
|
public TestServerRule build() {
|
||||||
return new TestServerRule(
|
return new TestServerRule(
|
||||||
|
@ -263,7 +274,8 @@ public final class TestServerRule extends ExternalResource {
|
||||||
checkNotNull(this.routes),
|
checkNotNull(this.routes),
|
||||||
checkNotNull(this.filters),
|
checkNotNull(this.filters),
|
||||||
checkNotNull(this.fixtures),
|
checkNotNull(this.fixtures),
|
||||||
checkNotNull(this.email));
|
checkNotNull(this.email),
|
||||||
|
this.gaeUserId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ contacts:
|
||||||
ADDED:
|
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}
|
{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:
|
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=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}
|
{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:
|
FINAL CONTENTS:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue