google-nomulus/javatests/google/registry/request/auth/AuthenticatedRegistrarAccessorTest.java
weiminyu 8a4407a9a1 Replace deprecated Mockito Matchers class
Part of the attempt to remove or suppress warnings for deprecated
API use, which will make the Gradle project usable with Intellij.

Currently in the Intellij/Gradle setup, deprecation warnings cause
Intellij build process to fail. Passing -Werror:none flags to javac\
does not have any effect.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=246135737
2019-05-06 16:21:27 -04:00

412 lines
16 KiB
Java

// Copyright 2018 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.request.auth;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.ADMIN;
import static google.registry.request.auth.AuthenticatedRegistrarAccessor.Role.OWNER;
import static google.registry.testing.AppEngineRule.THE_REGISTRAR_GAE_USER_ID;
import static google.registry.testing.DatastoreHelper.loadRegistrar;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.JUnitBackports.assertThrows;
import static google.registry.testing.LogsSubject.assertAboutLogs;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.flogger.LoggerConfig;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.TestLogHandler;
import dagger.Lazy;
import google.registry.groups.GroupsConnection;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
import google.registry.testing.AppEngineRule;
import google.registry.testing.InjectRule;
import java.util.Optional;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
/** Unit tests for {@link AuthenticatedRegistrarAccessor}. */
@RunWith(JUnit4.class)
public class AuthenticatedRegistrarAccessorTest {
@Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
@Rule public final InjectRule inject = new InjectRule();
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
@Mock private HttpServletRequest req;
@Mock private HttpServletResponse rsp;
@Mock private GroupsConnection groupsConnection;
@Mock private Lazy<GroupsConnection> lazyGroupsConnection;
private final TestLogHandler testLogHandler = new TestLogHandler();
private static final AuthResult USER = createAuthResult(false);
private static final AuthResult GAE_ADMIN = createAuthResult(true);
private static final AuthResult NO_USER = AuthResult.create(AuthLevel.NONE);
private static final Optional<String> SUPPORT_GROUP = Optional.of("support@registry.example");
/** Client ID of a REAL registrar with a RegistrarContact for USER and GAE_ADMIN. */
private static final String CLIENT_ID_WITH_CONTACT = "TheRegistrar";
/** Client ID of a REAL registrar without a RegistrarContact. */
private static final String REAL_CLIENT_ID_WITHOUT_CONTACT = "NewRegistrar";
/** Client ID of an OTE registrar without a RegistrarContact. */
private static final String OTE_CLIENT_ID_WITHOUT_CONTACT = "OteRegistrar";
/** Client ID of the Admin registrar without a RegistrarContact. */
private static final String ADMIN_CLIENT_ID = "AdminRegistrar";
/**
* Creates an AuthResult for a fake user.
*
* The user will be a RegistrarContact for "TheRegistrar", but not for "NewRegistrar".
*
* @param isAdmin if true, the user is an administrator for the app-engine project.
*/
private static AuthResult createAuthResult(boolean isAdmin) {
return AuthResult.create(
AuthLevel.USER,
UserAuthInfo.create(
new User(
String.format(
"%s@gmail.com",
isAdmin ? "admin" : "user"),
"gmail.com",
THE_REGISTRAR_GAE_USER_ID),
isAdmin));
}
@Before
public void before() {
when(lazyGroupsConnection.get()).thenReturn(groupsConnection);
LoggerConfig.getConfig(AuthenticatedRegistrarAccessor.class).addHandler(testLogHandler);
// persistResource(loadRegistrar(ADMIN_CLIENT_ID));
persistResource(
loadRegistrar(REAL_CLIENT_ID_WITHOUT_CONTACT)
.asBuilder()
.setClientId(OTE_CLIENT_ID_WITHOUT_CONTACT)
.setType(Registrar.Type.OTE)
.setIanaIdentifier(null)
.build());
persistResource(
loadRegistrar(REAL_CLIENT_ID_WITHOUT_CONTACT)
.asBuilder()
.setClientId(ADMIN_CLIENT_ID)
.setType(Registrar.Type.OTE)
.setIanaIdentifier(null)
.build());
when(groupsConnection.isMemberOfGroup(any(), any())).thenReturn(false);
}
@After
public void after() {
LoggerConfig.getConfig(AuthenticatedRegistrarAccessor.class).removeHandler(testLogHandler);
}
/** Users are owners for registrars if and only if they are in the contacts for that registrar. */
@Test
public void getAllClientIdWithAccess_user() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
assertThat(registrarAccessor.getAllClientIdWithRoles())
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
verify(lazyGroupsConnection).get();
}
/** Logged out users don't have access to anything. */
@Test
public void getAllClientIdWithAccess_loggedOutUser() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
NO_USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
assertThat(registrarAccessor.getAllClientIdWithRoles()).isEmpty();
verifyZeroInteractions(lazyGroupsConnection);
}
/**
* GAE admins have admin access to everything.
*
* <p>They also have OWNER access if they are in the RegistrarContacts.
*
* <p>They also have OWNER access to the Admin Registrar.
*
* <p>They also have OWNER access to non-REAL Registrars.
*
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
*/
@Test
public void getAllClientIdWithAccess_gaeAdmin() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
GAE_ADMIN, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
assertThat(registrarAccessor.getAllClientIdWithRoles())
.containsExactly(
CLIENT_ID_WITH_CONTACT, ADMIN,
CLIENT_ID_WITH_CONTACT, OWNER,
REAL_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
OTE_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
OTE_CLIENT_ID_WITHOUT_CONTACT, OWNER,
ADMIN_CLIENT_ID, ADMIN,
ADMIN_CLIENT_ID, OWNER);
verifyZeroInteractions(lazyGroupsConnection);
}
/**
* Users in support group have admin access to everything.
*
* <p>They also have OWNER access if they are in the RegistrarContacts.
*
* <p>They also have OWNER access to the Admin Registrar.
*
* <p>They also have OWNER access to non-REAL Registrars.
*
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
*/
@Test
public void getAllClientIdWithAccess_userInSupportGroup() {
when(groupsConnection.isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get())).thenReturn(true);
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
assertThat(registrarAccessor.getAllClientIdWithRoles())
.containsExactly(
CLIENT_ID_WITH_CONTACT, ADMIN,
CLIENT_ID_WITH_CONTACT, OWNER,
REAL_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
OTE_CLIENT_ID_WITHOUT_CONTACT, ADMIN,
OTE_CLIENT_ID_WITHOUT_CONTACT, OWNER,
ADMIN_CLIENT_ID, ADMIN,
ADMIN_CLIENT_ID, OWNER);
verify(lazyGroupsConnection).get();
}
/** Empty Support group email - skips check and doesn't generate the lazy. */
@Test
public void getAllClientIdWithAccess_emptySupportEmail_works() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
USER, ADMIN_CLIENT_ID, Optional.empty(), lazyGroupsConnection);
assertThat(registrarAccessor.getAllClientIdWithRoles())
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
// Make sure we didn't instantiate the lazyGroupsConnection
verifyZeroInteractions(lazyGroupsConnection);
}
/** 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(
USER, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
verify(groupsConnection).isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get());
assertThat(registrarAccessor.getAllClientIdWithRoles())
.containsExactly(CLIENT_ID_WITH_CONTACT, OWNER);
verify(lazyGroupsConnection).get();
}
/** Fail loading registrar if user doesn't have access to it. */
@Test
public void testGetRegistrarForUser_noAccess_isNotAdmin() {
expectGetRegistrarFailure(
REAL_CLIENT_ID_WITHOUT_CONTACT,
USER,
"user user@gmail.com doesn't have access to registrar NewRegistrar");
verify(lazyGroupsConnection).get();
}
@Test
public void testGetRegistrarForUser_registrarIsDisabled_isNotAdmin() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
.get()
.asBuilder()
.setState(State.DISABLED)
.build());
expectGetRegistrarFailure(
CLIENT_ID_WITH_CONTACT,
USER,
"user user@gmail.com doesn't have access to registrar TheRegistrar");
verify(lazyGroupsConnection).get();
}
/** Fail loading registrar if user doesn't have access to it, even if it's not REAL. */
@Test
public void testGetRegistrarForUser_noAccess_isNotAdmin_notReal() {
expectGetRegistrarFailure(
OTE_CLIENT_ID_WITHOUT_CONTACT,
USER,
"user user@gmail.com doesn't have access to registrar OteRegistrar");
verify(lazyGroupsConnection).get();
}
/** Fail loading registrar if there's no user associated with the request. */
@Test
public void testGetRegistrarForUser_noUser() {
expectGetRegistrarFailure(
CLIENT_ID_WITH_CONTACT,
NO_USER,
"<logged-out user> doesn't have access to registrar TheRegistrar");
verifyZeroInteractions(lazyGroupsConnection);
}
/** Succeed loading registrar if user has access to it. */
@Test
public void testGetRegistrarForUser_inContacts_isNotAdmin() throws Exception {
expectGetRegistrarSuccess(
CLIENT_ID_WITH_CONTACT,
USER,
"user user@gmail.com has [OWNER] access to registrar TheRegistrar");
verify(lazyGroupsConnection).get();
}
/** Succeed loading registrar if admin with access. */
@Test
public void testGetRegistrarForUser_inContacts_isAdmin() throws Exception {
expectGetRegistrarSuccess(
CLIENT_ID_WITH_CONTACT,
GAE_ADMIN,
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar TheRegistrar");
verifyZeroInteractions(lazyGroupsConnection);
}
/** Succeed loading registrar for admin even if they aren't on the approved contacts list. */
@Test
public void testGetRegistrarForUser_notInContacts_isAdmin() throws Exception {
expectGetRegistrarSuccess(
REAL_CLIENT_ID_WITHOUT_CONTACT,
GAE_ADMIN,
"admin admin@gmail.com has [ADMIN] access to registrar NewRegistrar.");
verifyZeroInteractions(lazyGroupsConnection);
}
@Test
public void testGetRegistrarForUser_registrarIsDisabled_isAdmin() throws Exception {
persistResource(
Registrar.loadByClientId("NewRegistrar")
.get()
.asBuilder()
.setState(State.DISABLED)
.build());
expectGetRegistrarSuccess(
REAL_CLIENT_ID_WITHOUT_CONTACT,
GAE_ADMIN,
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar NewRegistrar.");
verifyZeroInteractions(lazyGroupsConnection);
}
/** Succeed loading non-REAL registrar for admin. */
@Test
public void testGetRegistrarForUser_notInContacts_isAdmin_notReal() throws Exception {
expectGetRegistrarSuccess(
OTE_CLIENT_ID_WITHOUT_CONTACT,
GAE_ADMIN,
"admin admin@gmail.com has [OWNER, ADMIN] access to registrar OteRegistrar.");
verifyZeroInteractions(lazyGroupsConnection);
}
/** Fail loading registrar even if admin, if registrar doesn't exist. */
@Test
public void testGetRegistrarForUser_doesntExist_isAdmin() {
expectGetRegistrarFailure(
"BadClientId",
GAE_ADMIN,
"Registrar BadClientId does not exist");
verifyZeroInteractions(lazyGroupsConnection);
}
private void expectGetRegistrarSuccess(String clientId, AuthResult authResult, String message)
throws Exception {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
// make sure loading the registrar succeeds and returns a value
assertThat(registrarAccessor.getRegistrar(clientId)).isNotNull();
assertAboutLogs().that(testLogHandler).hasLogAtLevelWithMessage(Level.INFO, message);
}
private void expectGetRegistrarFailure(
String clientId, AuthResult authResult, String message) {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
authResult, ADMIN_CLIENT_ID, SUPPORT_GROUP, lazyGroupsConnection);
// make sure getRegistrar fails
RegistrarAccessDeniedException exception =
assertThrows(
RegistrarAccessDeniedException.class, () -> registrarAccessor.getRegistrar(clientId));
assertThat(exception).hasMessageThat().contains(message);
}
/** guessClientIdForUser returns the first clientId in getAllClientIdWithRoles. */
@Test
public void testGuessClientIdForUser_hasAccess_returnsFirst() throws Exception {
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(
ImmutableSetMultimap.of(
"clientId-1", OWNER,
"clientId-2", OWNER,
"clientId-2", ADMIN));
assertThat(registrarAccessor.guessClientId()).isEqualTo("clientId-1");
}
/** If a user doesn't have access to any registrars, guess fails. */
@Test
public void testGuessClientIdForUser_noAccess_fails() {
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
assertThat(assertThrows(RegistrarAccessDeniedException.class, registrarAccessor::guessClientId))
.hasMessageThat()
.isEqualTo("TestUserId isn't associated with any registrar");
}
@Test
public void testNullness() {
new NullPointerTester()
.setDefault(HttpServletRequest.class, req)
.setDefault(HttpServletResponse.class, rsp)
.testAllPublicStaticMethods(AuthenticatedRegistrarAccessor.class);
}
}