Fix error reply from RegistrarSettingsAction

RegistrarSettingsAction is a JSON in / JSON out endpoint, meaning the reply is consumed as JSON.

The current state is that if an error occurs, there are two possible replies:
- a JSON error reply is sent out, or
- a 402 HTML reply is sent out with the exception.getMessage()

The difference is only - do we actively catch the exception to translate it to JSON or not.

This fix catches ALL exceptions and translates them to JSON format. Note that there's no security change by giving the getMessage in the JSON reply since we were returning that anyway (in the HTML).

In addition - changed the "gaeUserId" to "user.getEmail" as the identifier, since it's clearer to the users who see that error - and I do want to transition to a more "email identifier" way of checking access (since that's what users put in the registrar contact info)

This too isn't leaking new information because
- the initial HTML page load already gives the user's email, and
- the logs already log the user's email for every request

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=215213807
This commit is contained in:
guyben 2018-10-01 07:57:29 -07:00 committed by jianglai
parent 2bf06eac77
commit 70273fa791
6 changed files with 45 additions and 33 deletions

View file

@ -17,7 +17,6 @@ package google.registry.ui.server.registrar;
import static com.google.common.truth.Truth.assertThat;
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.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.testing.TestDataHelper.loadFile;
@ -30,7 +29,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import google.registry.export.sheet.SyncRegistrarsSheetAction;
import google.registry.model.registrar.Registrar;
import google.registry.request.HttpException.ForbiddenException;
import google.registry.testing.CertificateSamples;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.CidrAddressBlock;
@ -84,8 +82,11 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
@Test
public void testFailure_readRegistrarInfo_notAuthorized() {
action.authResult = USER_UNAUTHORIZED;
assertThrows(
ForbiddenException.class, () -> action.handleJsonRequest(ImmutableMap.of("id", CLIENT_ID)));
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of("id", CLIENT_ID));
assertThat(response).containsExactly(
"status", "ERROR",
"results", ImmutableList.of(),
"message", "forbidden test error");
assertNoTasksEnqueued("sheet");
}
@ -145,14 +146,15 @@ public class RegistrarSettingsActionTest extends RegistrarSettingsActionTestCase
@Test
public void testFailute_updateRegistrarInfo_notAuthorized() {
action.authResult = USER_UNAUTHORIZED;
assertThrows(
ForbiddenException.class,
() ->
action.handleJsonRequest(
ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", ImmutableMap.of("lastUpdateTime", getLastUpdateTime()))));
Map<String, Object> response = action.handleJsonRequest(ImmutableMap.of(
"op", "update",
"id", CLIENT_ID,
"args", ImmutableMap.of("lastUpdateTime", getLastUpdateTime())));
assertThat(response).containsExactly(
"status", "ERROR",
"results", ImmutableList.of(),
"message", "forbidden test error");
assertNoTasksEnqueued("sheet");
}
@Test

View file

@ -112,6 +112,6 @@ public class RegistrarSettingsActionTestCase {
when(sessionUtils.getRegistrarForUser(CLIENT_ID, USER_AUTHORIZED))
.thenAnswer(x -> loadRegistrar(CLIENT_ID));
when(sessionUtils.getRegistrarForUser(CLIENT_ID, USER_UNAUTHORIZED))
.thenThrow(new ForbiddenException("forbidden"));
.thenThrow(new ForbiddenException("forbidden test error"));
}
}

View file

@ -68,8 +68,9 @@ public class SessionUtilsTest {
AuthLevel.USER,
UserAuthInfo.create(
new User(
"user1@google.com",
"google.com",
String.format(
"%s_%s@gmail.com", isAuthorized ? "good" : "evil", isAdmin ? "admin" : "user"),
"gmail.com",
isAuthorized ? THE_REGISTRAR_GAE_USER_ID : "badGaeUserId"),
isAdmin));
}
@ -211,8 +212,11 @@ public class SessionUtilsTest {
.that(testLogHandler)
.hasLogAtLevelWithMessage(
Level.INFO,
"Cannot associate admin user badGaeUserId with configured client Id."
+ " ClientId is null or empty.");
formatMessage(
"Cannot associate admin user {user} with configured client Id."
+ " ClientId is null or empty.",
UNAUTHORIZED_ADMIN,
null));
}
/**
@ -241,7 +245,7 @@ public class SessionUtilsTest {
assertThrows(ForbiddenException.class, () -> sessionUtils.guessClientIdForUser(authResult));
assertThat(exception)
.hasMessageThat()
.contains(formatMessage(message, UNAUTHORIZED_USER, null));
.contains(formatMessage(message, authResult, null));
}
@Test