From db1b92638fca23a3971e6e0ee8cfbc4d1072f2fd Mon Sep 17 00:00:00 2001 From: Pavlo Tkach <3469726+ptkach@users.noreply.github.com> Date: Wed, 31 May 2023 16:34:57 -0400 Subject: [PATCH] Create console settings contact endpoints (#2033) --- .../model/registrar/RegistrarPoc.java | 19 +- .../frontend/FrontendRequestComponent.java | 3 + .../registry/request/OptionalJsonPayload.java | 29 +++ .../registry/request/RequestModule.java | 16 +- .../console/settings/ContactAction.java | 145 +++++++++++ .../registrar/RegistrarConsoleModule.java | 25 ++ .../registrar/RegistrarSettingsAction.java | 2 +- .../console/settings/ContactActionTest.java | 231 ++++++++++++++++++ .../module/frontend/frontend_routing.txt | 23 +- 9 files changed, 470 insertions(+), 23 deletions(-) create mode 100644 core/src/main/java/google/registry/request/OptionalJsonPayload.java create mode 100644 core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java create mode 100644 core/src/test/java/google/registry/ui/server/console/settings/ContactActionTest.java diff --git a/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java b/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java index 1f9ac9e7c..b5c8d9b43 100644 --- a/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java +++ b/core/src/main/java/google/registry/model/registrar/RegistrarPoc.java @@ -29,6 +29,7 @@ import static java.util.stream.Collectors.joining; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import com.google.gson.annotations.Expose; import google.registry.model.Buildable; import google.registry.model.ImmutableObject; import google.registry.model.JsonMapBuilder; @@ -94,7 +95,7 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe } /** The name of the contact. */ - String name; + @Expose String name; /** * The contact email address of the contact. @@ -102,24 +103,24 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe *

This is different from the login email which is assgined to the regstrar and cannot be * changed. */ - @Id String emailAddress; + @Expose @Id String emailAddress; - @Id String registrarId; + @Expose @Id public String registrarId; /** External email address of this contact used for registry lock confirmations. */ String registryLockEmailAddress; /** The voice number of the contact. */ - String phoneNumber; + @Expose String phoneNumber; /** The fax number of the contact. */ - String faxNumber; + @Expose String faxNumber; /** * Multiple types are used to associate the registrar contact with various mailing groups. This * data is internal to the registry. */ - Set types; + @Expose Set types; /** A GAIA email address that was assigned to the registrar for console login purpose. */ String loginEmailAddress; @@ -127,19 +128,19 @@ public class RegistrarPoc extends ImmutableObject implements Jsonifiable, Unsafe /** * Whether this contact is publicly visible in WHOIS registrar query results as an Admin contact. */ - boolean visibleInWhoisAsAdmin = false; + @Expose boolean visibleInWhoisAsAdmin = false; /** * Whether this contact is publicly visible in WHOIS registrar query results as a Technical * contact. */ - boolean visibleInWhoisAsTech = false; + @Expose boolean visibleInWhoisAsTech = false; /** * Whether this contact's phone number and email address is publicly visible in WHOIS domain query * results as registrar abuse contact info. */ - boolean visibleInDomainWhoisAsAbuse = false; + @Expose boolean visibleInDomainWhoisAsAbuse = false; /** * Whether the contact is allowed to set their registry lock password through the registrar diff --git a/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java b/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java index a0bd284ff..c157ee1df 100644 --- a/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java +++ b/core/src/main/java/google/registry/module/frontend/FrontendRequestComponent.java @@ -26,6 +26,7 @@ import google.registry.request.RequestComponentBuilder; import google.registry.request.RequestModule; import google.registry.request.RequestScope; import google.registry.ui.server.console.ConsoleDomainGetAction; +import google.registry.ui.server.console.settings.ContactAction; import google.registry.ui.server.registrar.ConsoleOteSetupAction; import google.registry.ui.server.registrar.ConsoleRegistrarCreatorAction; import google.registry.ui.server.registrar.ConsoleUiAction; @@ -64,6 +65,8 @@ interface FrontendRequestComponent { ConsoleDomainGetAction consoleDomainGetAction(); + ContactAction contactAction(); + @Subcomponent.Builder abstract class Builder implements RequestComponentBuilder { @Override public abstract Builder requestModule(RequestModule requestModule); diff --git a/core/src/main/java/google/registry/request/OptionalJsonPayload.java b/core/src/main/java/google/registry/request/OptionalJsonPayload.java new file mode 100644 index 000000000..86e3b6d90 --- /dev/null +++ b/core/src/main/java/google/registry/request/OptionalJsonPayload.java @@ -0,0 +1,29 @@ +// Copyright 2023 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; + +import java.lang.annotation.Documented; +import javax.inject.Qualifier; + +/** + * Dagger qualifier for the HTTP request payload as parsed JSON wrapped in Optional. Can be used for + * any kind of request methods - GET, POST, etc. Will provide Optional.empty() if body is not + * present. + * + * @see RequestModule + */ +@Qualifier +@Documented +public @interface OptionalJsonPayload {} diff --git a/core/src/main/java/google/registry/request/RequestModule.java b/core/src/main/java/google/registry/request/RequestModule.java index 175ff845e..30c7bf4d2 100644 --- a/core/src/main/java/google/registry/request/RequestModule.java +++ b/core/src/main/java/google/registry/request/RequestModule.java @@ -31,6 +31,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; import com.google.common.io.CharStreams; import com.google.common.net.MediaType; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.google.protobuf.ByteString; import dagger.Module; import dagger.Provides; @@ -194,8 +196,7 @@ public final class RequestModule { @JsonPayload @SuppressWarnings("unchecked") static Map provideJsonPayload( - @Header("Content-Type") MediaType contentType, - @Payload String payload) { + @Header("Content-Type") MediaType contentType, @Payload String payload) { if (!JSON_UTF_8.is(contentType.withCharset(UTF_8))) { throw new UnsupportedMediaTypeException( String.format("Expected %s Content-Type", JSON_UTF_8.withoutParameters())); @@ -247,4 +248,15 @@ public final class RequestModule { static Optional provideCloudTasksRetryCount(HttpServletRequest req) { return extractOptionalHeader(req, CLOUD_TASKS_RETRY_HEADER).map(Integer::parseInt); } + + @Provides + @OptionalJsonPayload + public static Optional provideJsonBody(HttpServletRequest req, Gson gson) { + try { + JsonObject body = gson.fromJson(req.getReader(), JsonObject.class); + return Optional.of(body); + } catch (Exception e) { + return Optional.empty(); + } + } } diff --git a/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java b/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java new file mode 100644 index 000000000..2c3b6cd24 --- /dev/null +++ b/core/src/main/java/google/registry/ui/server/console/settings/ContactAction.java @@ -0,0 +1,145 @@ +// Copyright 2023 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.ui.server.console.settings; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static google.registry.persistence.transaction.TransactionManagerFactory.tm; +import static google.registry.request.Action.Method.GET; +import static google.registry.request.Action.Method.POST; + +import com.google.api.client.http.HttpStatusCodes; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.flogger.FluentLogger; +import com.google.gson.Gson; +import google.registry.model.console.ConsolePermission; +import google.registry.model.console.User; +import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.RegistrarPoc; +import google.registry.persistence.transaction.QueryComposer.Comparator; +import google.registry.request.Action; +import google.registry.request.Parameter; +import google.registry.request.Response; +import google.registry.request.auth.Auth; +import google.registry.request.auth.AuthResult; +import google.registry.ui.forms.FormException; +import google.registry.ui.server.registrar.JsonGetAction; +import google.registry.ui.server.registrar.RegistrarSettingsAction; +import java.util.Collections; +import java.util.Optional; +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; + +@Action( + service = Action.Service.DEFAULT, + path = ContactAction.PATH, + method = {GET, POST}, + auth = Auth.AUTH_PUBLIC_LOGGED_IN) +public class ContactAction implements JsonGetAction { + static final String PATH = "/console-api/settings/contacts/"; + private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + private final HttpServletRequest req; + private final AuthResult authResult; + private final Response response; + private final Gson gson; + private final Optional> contacts; + private final String registrarId; + + @Inject + public ContactAction( + HttpServletRequest req, + AuthResult authResult, + Response response, + Gson gson, + @Parameter("registrarId") String registrarId, + @Parameter("contacts") Optional> contacts) { + this.authResult = authResult; + this.response = response; + this.gson = gson; + this.registrarId = registrarId; + this.contacts = contacts; + this.req = req; + } + + @Override + public void run() { + User user = authResult.userAuthInfo().get().consoleUser().get(); + if (req.getMethod().equals(GET.toString())) { + getHandler(user); + } else { + postHandler(user); + } + } + + private void getHandler(User user) { + if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.VIEW_REGISTRAR_DETAILS)) { + response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN); + return; + } + + ImmutableList am = + tm().transact( + () -> + tm().createQueryComposer(RegistrarPoc.class) + .where("registrarId", Comparator.EQ, registrarId) + .list()); + + response.setStatus(HttpStatusCodes.STATUS_CODE_OK); + response.setPayload(gson.toJson(am)); + } + + private void postHandler(User user) { + if (!user.getUserRoles().hasPermission(registrarId, ConsolePermission.EDIT_REGISTRAR_DETAILS)) { + response.setStatus(HttpStatusCodes.STATUS_CODE_FORBIDDEN); + return; + } + + if (!contacts.isPresent()) { + response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST); + response.setPayload(gson.toJson("Contacts parameter is not present")); + return; + } + + Registrar registrar = + Registrar.loadByRegistrarId(registrarId) + .orElseThrow( + () -> + new IllegalArgumentException( + String.format("Unknown registrar %s", registrarId))); + + ImmutableSet oldContacts = registrar.getContacts(); + // TODO: @ptkach - refactor out contacts update functionality after RegistrarSettingsAction is + // deprecated + ImmutableSet updatedContacts = + RegistrarSettingsAction.readContacts( + registrar, + oldContacts, + Collections.singletonMap( + "contacts", + contacts.get().stream().map(c -> c.toJsonMap()).collect(toImmutableList()))); + try { + RegistrarSettingsAction.checkContactRequirements(oldContacts, updatedContacts); + } catch (FormException e) { + logger.atWarning().withCause(e).log( + "Error processing contacts post request for registrar: %s", registrarId); + response.setStatus(HttpStatusCodes.STATUS_CODE_BAD_REQUEST); + response.setPayload(e.getMessage()); + return; + } + + RegistrarPoc.updateContacts(registrar, updatedContacts); + response.setStatus(HttpStatusCodes.STATUS_CODE_OK); + } +} diff --git a/core/src/main/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java b/core/src/main/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java index f78ca9c94..9061cb9ab 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java +++ b/core/src/main/java/google/registry/ui/server/registrar/RegistrarConsoleModule.java @@ -19,8 +19,13 @@ import static google.registry.request.RequestParameters.extractOptionalIntParame import static google.registry.request.RequestParameters.extractOptionalParameter; import static google.registry.request.RequestParameters.extractRequiredParameter; +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import dagger.Module; import dagger.Provides; +import google.registry.model.registrar.RegistrarPoc; +import google.registry.request.OptionalJsonPayload; import google.registry.request.Parameter; import java.util.Optional; import javax.servlet.http.HttpServletRequest; @@ -162,4 +167,24 @@ public final class RegistrarConsoleModule { static String provideDomain(HttpServletRequest req) { return extractRequiredParameter(req, "domain"); } + + @Provides + @Parameter("contacts") + public static Optional> provideContacts( + Gson gson, @OptionalJsonPayload Optional 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(); + } + + @Provides + @Parameter("registrarId") + static String provideRegistrarId(HttpServletRequest req) { + return extractRequiredParameter(req, "registrarId"); + } } diff --git a/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java b/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java index f45cae0b5..e8ce54132 100644 --- a/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java +++ b/core/src/main/java/google/registry/ui/server/registrar/RegistrarSettingsAction.java @@ -473,7 +473,7 @@ public class RegistrarSettingsAction implements Runnable, JsonActionRunner.JsonA * * @throws FormException if the checks fail. */ - void checkContactRequirements( + public static void checkContactRequirements( ImmutableSet existingContacts, ImmutableSet updatedContacts) { // Check that no two contacts use the same email address. Set emails = new HashSet<>(); diff --git a/core/src/test/java/google/registry/ui/server/console/settings/ContactActionTest.java b/core/src/test/java/google/registry/ui/server/console/settings/ContactActionTest.java new file mode 100644 index 000000000..921a68e4a --- /dev/null +++ b/core/src/test/java/google/registry/ui/server/console/settings/ContactActionTest.java @@ -0,0 +1,231 @@ +// Copyright 2023 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.ui.server.console.settings; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.truth.Truth.assertThat; +import static google.registry.model.registrar.RegistrarPoc.Type.WHOIS; +import static google.registry.testing.DatabaseHelper.insertInDb; +import static google.registry.testing.DatabaseHelper.loadAllOf; +import static google.registry.testing.SqlHelper.saveRegistrar; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.api.client.http.HttpStatusCodes; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import google.registry.model.console.GlobalRole; +import google.registry.model.console.RegistrarRole; +import google.registry.model.console.User; +import google.registry.model.console.UserRoles; +import google.registry.model.registrar.Registrar; +import google.registry.model.registrar.RegistrarPoc; +import google.registry.persistence.transaction.JpaTestExtensions; +import google.registry.request.Action; +import google.registry.request.RequestModule; +import google.registry.request.auth.AuthResult; +import google.registry.request.auth.AuthSettings.AuthLevel; +import google.registry.request.auth.UserAuthInfo; +import google.registry.testing.FakeResponse; +import google.registry.ui.server.registrar.RegistrarConsoleModule; +import google.registry.util.UtilsModule; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Optional; +import javax.servlet.http.HttpServletRequest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** Tests for {@link google.registry.ui.server.console.settings.ContactAction}. */ +class ContactActionTest { + private static String jsonRegistrar1 = + "{\"name\":\"Test Registrar 1\"," + + "\"emailAddress\":\"test.registrar1@example.com\"," + + "\"registrarId\":\"registrarId\"," + + "\"phoneNumber\":\"+1.9999999999\",\"faxNumber\":\"+1.9999999991\"," + + "\"types\":[\"WHOIS\"],\"visibleInWhoisAsAdmin\":true," + + "\"visibleInWhoisAsTech\":false,\"visibleInDomainWhoisAsAbuse\":false}"; + + private static String jsonRegistrar2 = + "{\"name\":\"Test Registrar 2\"," + + "\"emailAddress\":\"test.registrar2@example.com\"," + + "\"registrarId\":\"registrarId\"," + + "\"phoneNumber\":\"+1.1234567890\",\"faxNumber\":\"+1.1234567891\"," + + "\"types\":[\"WHOIS\"],\"visibleInWhoisAsAdmin\":true," + + "\"visibleInWhoisAsTech\":false,\"visibleInDomainWhoisAsAbuse\":false}"; + + private Registrar testRegistrar; + private final HttpServletRequest request = mock(HttpServletRequest.class); + private RegistrarPoc testRegistrarPoc; + private static final Gson GSON = UtilsModule.provideGson(); + private static final FakeResponse RESPONSE = new FakeResponse(); + + @RegisterExtension + final JpaTestExtensions.JpaIntegrationTestExtension jpa = + new JpaTestExtensions.Builder().buildIntegrationTestExtension(); + + @BeforeEach + void beforeEach() { + testRegistrar = saveRegistrar("registrarId"); + testRegistrarPoc = + new RegistrarPoc.Builder() + .setRegistrar(testRegistrar) + .setName("Test Registrar 1") + .setEmailAddress("test.registrar1@example.com") + .setPhoneNumber("+1.9999999999") + .setFaxNumber("+1.9999999991") + .setTypes(ImmutableSet.of(WHOIS)) + .setVisibleInWhoisAsAdmin(true) + .setVisibleInWhoisAsTech(false) + .setVisibleInDomainWhoisAsAbuse(false) + .build(); + } + + @Test + void testSuccess_getContactInfo() throws IOException { + insertInDb(testRegistrarPoc); + ContactAction action = + createAction( + Action.Method.GET, + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))), + testRegistrar.getRegistrarId(), + null); + action.run(); + assertThat(RESPONSE.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK); + assertThat(RESPONSE.getPayload()).isEqualTo("[" + jsonRegistrar1 + "]"); + } + + @Test + void testSuccess_postCreateContactInfo() throws IOException { + ContactAction action = + createAction( + Action.Method.POST, + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))), + testRegistrar.getRegistrarId(), + "[" + jsonRegistrar1 + "," + jsonRegistrar2 + "]"); + action.run(); + assertThat(RESPONSE.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK); + assertThat( + loadAllOf(RegistrarPoc.class).stream() + .filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId())) + .map(r -> r.getName()) + .collect(toImmutableList())) + .containsExactly("Test Registrar 1", "Test Registrar 2"); + } + + @Test + void testSuccess_postUpdateContactInfo() throws IOException { + testRegistrarPoc = testRegistrarPoc.asBuilder().setEmailAddress("incorrect@email.com").build(); + insertInDb(testRegistrarPoc); + ContactAction action = + createAction( + Action.Method.POST, + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))), + testRegistrar.getRegistrarId(), + "[" + jsonRegistrar1 + "," + jsonRegistrar2 + "]"); + action.run(); + assertThat(RESPONSE.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK); + HashMap testResult = new HashMap<>(); + loadAllOf(RegistrarPoc.class).stream() + .filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId())) + .forEach(r -> testResult.put(r.getName(), r.getEmailAddress())); + assertThat(testResult) + .containsExactly( + "Test Registrar 1", + "test.registrar1@example.com", + "Test Registrar 2", + "test.registrar2@example.com"); + } + + @Test + void testSuccess_postDeleteContactInfo() throws IOException { + insertInDb(testRegistrarPoc); + ContactAction action = + createAction( + Action.Method.POST, + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + createUser(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()))), + testRegistrar.getRegistrarId(), + "[" + jsonRegistrar2 + "]"); + action.run(); + assertThat(RESPONSE.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK); + assertThat( + loadAllOf(RegistrarPoc.class).stream() + .filter(r -> r.registrarId.equals(testRegistrar.getRegistrarId())) + .map(r -> r.getName()) + .collect(toImmutableList())) + .containsExactly("Test Registrar 2"); + } + + @Test + void testFailure_postDeleteContactInfo_missingPermission() throws IOException { + insertInDb(testRegistrarPoc); + ContactAction action = + createAction( + Action.Method.POST, + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + createUser( + new UserRoles.Builder() + .setRegistrarRoles( + ImmutableMap.of( + testRegistrar.getRegistrarId(), RegistrarRole.ACCOUNT_MANAGER)) + .build()))), + testRegistrar.getRegistrarId(), + "[" + jsonRegistrar2 + "]"); + action.run(); + assertThat(RESPONSE.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_FORBIDDEN); + } + + private User createUser(UserRoles userRoles) { + return new User.Builder() + .setEmailAddress("email@email.com") + .setGaiaId("gaiaId") + .setUserRoles(userRoles) + .build(); + } + + private ContactAction createAction( + Action.Method method, AuthResult authResult, String registrarId, String contacts) + throws IOException { + when(request.getMethod()).thenReturn(method.toString()); + 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 + "}"))); + Optional> maybeContacts = + RegistrarConsoleModule.provideContacts( + GSON, RequestModule.provideJsonBody(request, GSON)); + return new ContactAction(request, authResult, RESPONSE, GSON, registrarId, maybeContacts); + } + } +} diff --git a/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt b/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt index fbc0f9ba7..cd25f3d1a 100644 --- a/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt +++ b/core/src/test/resources/google/registry/module/frontend/frontend_routing.txt @@ -1,11 +1,12 @@ -PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY -/_dr/epp EppTlsAction POST n INTERNAL,API APP PUBLIC -/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC -/registrar ConsoleUiAction GET n INTERNAL,API,LEGACY NONE PUBLIC -/registrar-create ConsoleRegistrarCreatorAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC -/registrar-ote-setup ConsoleOteSetupAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC -/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC -/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC -/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC -/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC -/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY USER PUBLIC +PATH CLASS METHODS OK AUTH_METHODS MIN USER_POLICY +/_dr/epp EppTlsAction POST n INTERNAL,API APP PUBLIC +/console-api/domain ConsoleDomainGetAction GET n API,LEGACY USER PUBLIC +/console-api/settings/contacts/ ContactAction GET,POST n API,LEGACY USER PUBLIC +/registrar ConsoleUiAction GET n INTERNAL,API,LEGACY NONE PUBLIC +/registrar-create ConsoleRegistrarCreatorAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC +/registrar-ote-setup ConsoleOteSetupAction POST,GET n INTERNAL,API,LEGACY NONE PUBLIC +/registrar-ote-status OteStatusAction POST n API,LEGACY USER PUBLIC +/registrar-settings RegistrarSettingsAction POST n API,LEGACY USER PUBLIC +/registry-lock-get RegistryLockGetAction GET n API,LEGACY USER PUBLIC +/registry-lock-post RegistryLockPostAction POST n API,LEGACY USER PUBLIC +/registry-lock-verify RegistryLockVerifyAction GET n API,LEGACY USER PUBLIC