mirror of
https://github.com/google/nomulus.git
synced 2025-08-01 23:42:12 +02:00
Add support G-Suite group whose members have ADMIN access to registrar console
After this CL, "support" accounts (accounts that are part of the "support" G-Suite group) will the same access to the registrar console as GCP "admins". However, they don't won't have access to the GCP project itself. We could give them their own Role in the future (say SUPPORT) and give them different access than "admins", but right now we don't need it and YAGNI or something :) NOTE: we identify users by their email (they need to be logged in to a google account). I don't know if that's best practice, since I guess different google accounts might have the same email address. However, G-Suite groups' membership is by email so there's not much we can do about it if we want to use G-Suite groups. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=220804273
This commit is contained in:
parent
783c010ab4
commit
557984bb75
15 changed files with 285 additions and 25 deletions
|
@ -216,6 +216,45 @@ public class DirectoryGroupsConnectionTest {
|
|||
assertThat(connection.getMembersOfGroup("nonexistent_group@fake.notreal")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_isMemberOfSupportGroup_userInGroup_True() throws Exception {
|
||||
when(members.get("support@domain-registry.example", "user@example.com")).thenReturn(membersGet);
|
||||
when(membersGet.execute()).thenReturn(new Member());
|
||||
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_isMemberOfSupportGroup_userExistButNotInGroup_returnsFalse() throws Exception {
|
||||
when(members.get("support@domain-registry.example", "user@example.com"))
|
||||
.thenThrow(makeResponseException(0, "Resource Not Found: memberKey"));
|
||||
when(membersGet.execute()).thenReturn(new Member());
|
||||
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_isMemberOfSupportGroup_userDoesntExist_returnsFalse() throws Exception {
|
||||
when(members.get("support@domain-registry.example", "user@example.com"))
|
||||
.thenThrow(makeResponseException(0, "Missing required field: memberKey"));
|
||||
when(membersGet.execute()).thenReturn(new Member());
|
||||
assertThat(connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_isMemberOfSupportGroup_otherError_throws() throws Exception {
|
||||
when(members.get("support@domain-registry.example", "user@example.com"))
|
||||
.thenThrow(makeResponseException(0, "some error"));
|
||||
when(membersGet.execute()).thenReturn(new Member());
|
||||
RuntimeException e =
|
||||
assertThrows(
|
||||
RuntimeException.class,
|
||||
() ->
|
||||
connection.isMemberOfGroup("user@example.com", "support@domain-registry.example"));
|
||||
assertThat(e).hasCauseThat().isInstanceOf(GoogleJsonResponseException.class);
|
||||
}
|
||||
|
||||
/** Runs a full test to add a member to the group and returns the expected Member. */
|
||||
private Member runAddMemberTest() throws Exception {
|
||||
connection.addMemberToGroup("spam@example.com", "jim@example.com", Role.MEMBER);
|
||||
|
|
|
@ -22,12 +22,17 @@ import static google.registry.testing.JUnitBackports.assertThrows;
|
|||
import static google.registry.testing.LogsSubject.assertAboutLogs;
|
||||
import static google.registry.ui.server.registrar.AuthenticatedRegistrarAccessor.Role.ADMIN;
|
||||
import static google.registry.ui.server.registrar.AuthenticatedRegistrarAccessor.Role.OWNER;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.appengine.api.users.User;
|
||||
import com.google.common.flogger.LoggerConfig;
|
||||
import com.google.common.testing.NullPointerTester;
|
||||
import com.google.common.testing.TestLogHandler;
|
||||
import google.registry.groups.GroupsConnection;
|
||||
import google.registry.request.HttpException.ForbiddenException;
|
||||
import google.registry.request.auth.AuthLevel;
|
||||
import google.registry.request.auth.AuthResult;
|
||||
|
@ -53,6 +58,7 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
|
||||
private final HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
private final HttpServletResponse rsp = mock(HttpServletResponse.class);
|
||||
private final GroupsConnection groupsConnection = mock(GroupsConnection.class);
|
||||
private final TestLogHandler testLogHandler = new TestLogHandler();
|
||||
|
||||
private static final AuthResult AUTHORIZED_USER = createAuthResult(true, false);
|
||||
|
@ -60,6 +66,7 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
private static final AuthResult AUTHORIZED_ADMIN = createAuthResult(true, true);
|
||||
private static final AuthResult UNAUTHORIZED_ADMIN = createAuthResult(false, true);
|
||||
private static final AuthResult NO_USER = AuthResult.create(AuthLevel.NONE);
|
||||
private static final String SUPPORT_GROUP = "support@registry.example";
|
||||
private static final String DEFAULT_CLIENT_ID = "TheRegistrar";
|
||||
private static final String ADMIN_CLIENT_ID = "NewRegistrar";
|
||||
|
||||
|
@ -79,6 +86,7 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
public void before() {
|
||||
LoggerConfig.getConfig(AuthenticatedRegistrarAccessor.class).addHandler(testLogHandler);
|
||||
persistResource(loadRegistrar(ADMIN_CLIENT_ID));
|
||||
when(groupsConnection.isMemberOfGroup(any(), any())).thenReturn(false);
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -96,17 +104,34 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void getAllClientIdWithAccess_authorizedUser() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(AUTHORIZED_USER, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(DEFAULT_CLIENT_ID, OWNER);
|
||||
}
|
||||
|
||||
/** Users in support group have admin access to everything. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_authorizedUser_isSupportGroup() {
|
||||
when(groupsConnection.isMemberOfGroup("good_user@gmail.com", SUPPORT_GROUP)).thenReturn(true);
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(
|
||||
DEFAULT_CLIENT_ID, OWNER,
|
||||
DEFAULT_CLIENT_ID, ADMIN,
|
||||
ADMIN_CLIENT_ID, ADMIN);
|
||||
}
|
||||
|
||||
/** Logged out users don't have access to anything. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_loggedOutUser() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(NO_USER, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
NO_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles()).isEmpty();
|
||||
}
|
||||
|
@ -115,16 +140,56 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void getAllClientIdWithAccess_unauthorizedUser() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_USER, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
UNAUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles()).isEmpty();
|
||||
}
|
||||
|
||||
/** Unauthorized users who are in support group have admin access. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_unauthorizedUser_inSupportGroup() {
|
||||
when(groupsConnection.isMemberOfGroup("evil_user@gmail.com", SUPPORT_GROUP)).thenReturn(true);
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
UNAUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(
|
||||
DEFAULT_CLIENT_ID, ADMIN,
|
||||
ADMIN_CLIENT_ID, ADMIN);
|
||||
}
|
||||
|
||||
/** Empty Support group email - skips check. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_emptySupportEmail_works() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(AUTHORIZED_USER, ADMIN_CLIENT_ID, "", groupsConnection);
|
||||
|
||||
verifyNoMoreInteractions(groupsConnection);
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(DEFAULT_CLIENT_ID, OWNER);
|
||||
}
|
||||
|
||||
/** Support group check throws - continue anyway. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_throwingGroupCheck_stillWorks() {
|
||||
when(groupsConnection.isMemberOfGroup(any(), any())).thenThrow(new RuntimeException("blah"));
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
verify(groupsConnection).isMemberOfGroup("good_user@gmail.com", SUPPORT_GROUP);
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(DEFAULT_CLIENT_ID, OWNER);
|
||||
}
|
||||
|
||||
/** Admins have read/write access to the authorized registrars, AND the admin registrar. */
|
||||
@Test
|
||||
public void getAllClientIdWithAccess_authorizedAdmin() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(AUTHORIZED_ADMIN, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(
|
||||
|
@ -141,7 +206,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void getAllClientIdWithAccess_unauthorizedAdmin() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_ADMIN, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
UNAUTHORIZED_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getAllClientIdWithRoles())
|
||||
.containsExactly(
|
||||
|
@ -199,7 +265,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
private void expectGetRegistrarSuccess(
|
||||
AuthResult authResult, String message) {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(authResult, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.getRegistrar(DEFAULT_CLIENT_ID)).isNotNull();
|
||||
assertAboutLogs()
|
||||
|
@ -211,7 +278,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
private void expectGetRegistrarFailure(
|
||||
String clientId, AuthResult authResult, String message) {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(authResult, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
ForbiddenException exception =
|
||||
assertThrows(
|
||||
|
@ -224,7 +292,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void testGuessClientIdForUser_hasAccess_isNotAdmin() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(AUTHORIZED_USER, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.guessClientId()).isEqualTo(DEFAULT_CLIENT_ID);
|
||||
}
|
||||
|
@ -242,7 +311,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void testGuessClientIdForUser_hasAccess_isAdmin() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(AUTHORIZED_ADMIN, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
AUTHORIZED_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.guessClientId()).isEqualTo(DEFAULT_CLIENT_ID);
|
||||
}
|
||||
|
@ -251,7 +321,8 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void testGuessClientIdForUser_noAccess_isAdmin() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_ADMIN, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
UNAUTHORIZED_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.guessClientId()).isEqualTo(ADMIN_CLIENT_ID);
|
||||
}
|
||||
|
@ -264,7 +335,7 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void testGuessClientIdForUser_noAccess_isAdmin_adminClientIdEmpty() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_ADMIN, "");
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_ADMIN, "", SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.guessClientId()).isAnyOf(ADMIN_CLIENT_ID, DEFAULT_CLIENT_ID);
|
||||
}
|
||||
|
@ -276,14 +347,16 @@ public class AuthenticatedRegistrarAccessorTest {
|
|||
@Test
|
||||
public void testGuessClientIdForUser_noAccess_isAdmin_adminClientIdInvalid() {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(UNAUTHORIZED_ADMIN, "NonexistentRegistrar");
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
UNAUTHORIZED_ADMIN, "NonexistentRegistrar", SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
assertThat(registrarAccessor.guessClientId()).isEqualTo("NonexistentRegistrar");
|
||||
}
|
||||
|
||||
private void expectGuessRegistrarFailure(AuthResult authResult, String message) {
|
||||
AuthenticatedRegistrarAccessor registrarAccessor =
|
||||
new AuthenticatedRegistrarAccessor(authResult, ADMIN_CLIENT_ID);
|
||||
new AuthenticatedRegistrarAccessor(
|
||||
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, groupsConnection);
|
||||
|
||||
ForbiddenException exception =
|
||||
assertThrows(ForbiddenException.class, () -> registrarAccessor.guessClientId());
|
||||
|
|
|
@ -14,6 +14,7 @@ java_library(
|
|||
deps = [
|
||||
"//java/google/registry/config",
|
||||
"//java/google/registry/export/sheet",
|
||||
"//java/google/registry/groups",
|
||||
"//java/google/registry/model",
|
||||
"//java/google/registry/request",
|
||||
"//java/google/registry/request/auth",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue