1
0
mirror of https://github.com/google/nomulus synced 2026-06-07 07:22:55 +00:00

Refactor the way that the console BE parses POST bodies (#2113)

This includes two changes:
1. Creating a base string-type adapter for use parsing to/from JSON
   classes that are represented as simple strings
2. Changing the object-provider methods so that the POST bodies should
   contain precisely the expected object(s) and nothing else. This way,
   it's easier for the frontend and backend to agree that, for instance,
   one POST endpoint might accept exactly a Registrar object, or a list
   of Contact objects.
This commit is contained in:
gbrodman
2023-08-17 15:51:21 -04:00
committed by GitHub
parent 655f05c58c
commit 9f551eb552
10 changed files with 69 additions and 80 deletions

View File

@@ -14,26 +14,17 @@
package google.registry.model.adapters;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import google.registry.model.adapters.CurrencyUnitAdapter.UnknownCurrencyException;
import google.registry.util.StringBaseTypeAdapter;
import java.io.IOException;
import org.joda.money.CurrencyUnit;
public class CurrencyJsonAdapter extends TypeAdapter<CurrencyUnit> {
public class CurrencyJsonAdapter extends StringBaseTypeAdapter<CurrencyUnit> {
@Override
public void write(JsonWriter out, CurrencyUnit value) throws IOException {
String currency = CurrencyUnitAdapter.convertFromCurrency(value);
out.value(currency);
}
@Override
public CurrencyUnit read(JsonReader in) throws IOException {
String currency = in.nextString();
protected CurrencyUnit fromString(String stringValue) throws IOException {
try {
return CurrencyUnitAdapter.convertFromString(currency);
return CurrencyUnitAdapter.convertFromString(stringValue);
} catch (UnknownCurrencyException e) {
throw new IOException("Unknown currency");
}

View File

@@ -32,7 +32,7 @@ import com.google.common.io.CharStreams;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonElement;
import com.google.protobuf.ByteString;
import dagger.Module;
import dagger.Provides;
@@ -263,11 +263,10 @@ public final class RequestModule {
@Provides
@OptionalJsonPayload
public static Optional<JsonObject> provideJsonBody(HttpServletRequest req, Gson gson) {
public static Optional<JsonElement> provideJsonBody(HttpServletRequest req, Gson gson) {
try {
JsonObject body = gson.fromJson(req.getReader(), JsonObject.class);
return Optional.of(body);
} catch (Exception e) {
return Optional.of(gson.fromJson(req.getReader(), JsonElement.class));
} catch (IOException e) {
return Optional.empty();
}
}

View File

@@ -21,7 +21,7 @@ import static google.registry.request.RequestParameters.extractRequiredParameter
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonElement;
import dagger.Module;
import dagger.Provides;
import google.registry.model.registrar.Registrar;
@@ -172,15 +172,8 @@ public final class RegistrarConsoleModule {
@Provides
@Parameter("contacts")
public static Optional<ImmutableSet<RegistrarPoc>> provideContacts(
Gson gson, @OptionalJsonPayload Optional<JsonObject> payload) {
if (payload.isPresent() && payload.get().has("contacts")) {
return Optional.of(
ImmutableSet.copyOf(
gson.fromJson(payload.get().get("contacts").getAsJsonArray(), RegistrarPoc[].class)));
}
return Optional.empty();
Gson gson, @OptionalJsonPayload Optional<JsonElement> payload) {
return payload.map(s -> ImmutableSet.copyOf(gson.fromJson(s, RegistrarPoc[].class)));
}
@Provides
@@ -192,11 +185,7 @@ public final class RegistrarConsoleModule {
@Provides
@Parameter("registrar")
public static Optional<Registrar> provideRegistrar(
Gson gson, @OptionalJsonPayload Optional<JsonObject> payload) {
if (payload.isPresent() && payload.get().has("registrar")) {
return Optional.of(gson.fromJson(payload.get().get("registrar"), Registrar.class));
}
return Optional.empty();
Gson gson, @OptionalJsonPayload Optional<JsonElement> payload) {
return payload.map(s -> gson.fromJson(s, Registrar.class));
}
}

View File

@@ -251,9 +251,7 @@ class RegistrarsActionTest {
passcodeGenerator);
} else {
try {
doReturn(
new BufferedReader(
new StringReader("{\"registrar\":" + registrarParamMap.toString() + "}")))
doReturn(new BufferedReader(new StringReader(registrarParamMap.toString())))
.when(request)
.getReader();
} catch (IOException e) {

View File

@@ -238,8 +238,7 @@ class ContactActionTest {
if (method.equals(Action.Method.GET)) {
return new ContactAction(request, authResult, response, GSON, registrarId, Optional.empty());
} else {
when(request.getReader())
.thenReturn(new BufferedReader(new StringReader("{\"contacts\":" + contacts + "}")));
when(request.getReader()).thenReturn(new BufferedReader(new StringReader(contacts)));
Optional<ImmutableSet<RegistrarPoc>> maybeContacts =
RegistrarConsoleModule.provideContacts(
GSON, RequestModule.provideJsonBody(request, GSON));

View File

@@ -116,12 +116,9 @@ class SecurityActionTest {
private SecurityAction createAction(AuthResult authResult, String registrarId)
throws IOException {
doReturn(new BufferedReader(new StringReader("{\"registrar\":" + jsonRegistrar1 + "}")))
.when(request)
.getReader();
Optional<Registrar> maybeRegistrar =
RegistrarConsoleModule.provideRegistrar(
GSON, RequestModule.provideJsonBody(request, GSON));
doReturn(new BufferedReader(new StringReader(jsonRegistrar1))).when(request).getReader();
Optional<Registrar> maybeRegistrar =
RegistrarConsoleModule.provideRegistrar(GSON, RequestModule.provideJsonBody(request, GSON));
return new SecurityAction(
authResult,
response,