From 9434d01234c8d3d53c659c03d90d812633941d63 Mon Sep 17 00:00:00 2001 From: Pavlo Tkach <3469726+ptkach@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:29:53 -0400 Subject: [PATCH] Add /console/userdata endpoint (#2137) Provides initial set of data, necessary to start the UI --- .../frontend/FrontendRequestComponent.java | 20 +++-- .../server/console/ConsoleUserDataAction.java | 83 ++++++++++++++++++ .../console/ConsoleUserDataActionTest.java | 85 +++++++++++++++++++ .../module/frontend/frontend_routing.txt | 1 + 4 files changed, 180 insertions(+), 9 deletions(-) create mode 100644 core/src/main/java/google/registry/ui/server/console/ConsoleUserDataAction.java create mode 100644 core/src/test/java/google/registry/ui/server/console/ConsoleUserDataActionTest.java 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 f9cb09fe8..7df6a1bb1 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.ConsoleUserDataAction; import google.registry.ui.server.console.RegistrarsAction; import google.registry.ui.server.console.settings.ContactAction; import google.registry.ui.server.console.settings.SecurityAction; @@ -52,28 +53,29 @@ import google.registry.ui.server.registrar.RegistryLockVerifyAction; WhiteboxModule.class, }) interface FrontendRequestComponent { + ConsoleDomainGetAction consoleDomainGetAction(); + ConsoleOteSetupAction consoleOteSetupAction(); ConsoleRegistrarCreatorAction consoleRegistrarCreatorAction(); ConsoleUiAction consoleUiAction(); + + ConsoleUserDataAction consoleUserDataAction(); + + ContactAction contactAction(); + EppTlsAction eppTlsAction(); FlowComponent.Builder flowComponentBuilder(); OteStatusAction oteStatusAction(); + + RegistrarsAction registrarsAction(); + RegistrarSettingsAction registrarSettingsAction(); RegistryLockGetAction registryLockGetAction(); RegistryLockPostAction registryLockPostAction(); - RegistryLockVerifyAction registryLockVerifyAction(); - - ConsoleDomainGetAction consoleDomainGetAction(); - - ContactAction contactAction(); - - RegistrarsAction registrarsAction(); - SecurityAction securityAction(); - WhoisRegistrarFieldsAction whoisRegistrarFieldsAction(); @Subcomponent.Builder diff --git a/core/src/main/java/google/registry/ui/server/console/ConsoleUserDataAction.java b/core/src/main/java/google/registry/ui/server/console/ConsoleUserDataAction.java new file mode 100644 index 000000000..1fbbd82cb --- /dev/null +++ b/core/src/main/java/google/registry/ui/server/console/ConsoleUserDataAction.java @@ -0,0 +1,83 @@ +// 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; + +import static google.registry.request.Action.Method.GET; + +import com.google.api.client.http.HttpStatusCodes; +import com.google.common.collect.ImmutableMap; +import google.registry.config.RegistryConfig.Config; +import google.registry.model.console.User; +import google.registry.request.Action; +import google.registry.request.Response; +import google.registry.request.auth.Auth; +import google.registry.request.auth.AuthResult; +import google.registry.request.auth.UserAuthInfo; +import google.registry.ui.server.registrar.JsonGetAction; +import javax.inject.Inject; +import org.json.JSONObject; + +@Action( + service = Action.Service.DEFAULT, + path = ConsoleUserDataAction.PATH, + method = {GET}, + auth = Auth.AUTH_PUBLIC_LOGGED_IN) +public class ConsoleUserDataAction implements JsonGetAction { + + public static final String PATH = "/console-api/userdata"; + + private final AuthResult authResult; + private final Response response; + private final String technicalDocsUrl; + + @Inject + public ConsoleUserDataAction( + AuthResult authResult, + Response response, + @Config("technicalDocsUrl") String technicalDocsUrl) { + this.response = response; + this.authResult = authResult; + this.technicalDocsUrl = technicalDocsUrl; + } + + @Override + public void run() { + UserAuthInfo authInfo = authResult.userAuthInfo().get(); + if (!authInfo.consoleUser().isPresent()) { + response.setStatus(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED); + return; + } + User user = authInfo.consoleUser().get(); + + JSONObject json = + new JSONObject( + ImmutableMap.of( + // Both isAdmin and globalRole flags are used by UI as an indicator to hide / show + // specific set of widgets and screens. + // For example: + // - Admin sees everything and can create other users + // - Empty global role indicates registrar user, with access to registrar specific + // screens and widgets. + // This however is merely for visual representation, as any back-end action contains + // auth checks. + "isAdmin", user.getUserRoles().isAdmin(), + "globalRole", user.getUserRoles().getGlobalRole(), + // Is used by UI to construct a link to registry resources + "technicalDocsUrl", technicalDocsUrl)); + + response.setPayload(json.toString()); + response.setStatus(HttpStatusCodes.STATUS_CODE_OK); + } +} diff --git a/core/src/test/java/google/registry/ui/server/console/ConsoleUserDataActionTest.java b/core/src/test/java/google/registry/ui/server/console/ConsoleUserDataActionTest.java new file mode 100644 index 000000000..cda77bbc3 --- /dev/null +++ b/core/src/test/java/google/registry/ui/server/console/ConsoleUserDataActionTest.java @@ -0,0 +1,85 @@ +// 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; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; + +import com.google.api.client.http.HttpStatusCodes; +import com.google.gson.Gson; +import google.registry.model.console.GlobalRole; +import google.registry.model.console.User; +import google.registry.model.console.UserRoles; +import google.registry.model.registrar.RegistrarPoc; +import google.registry.persistence.transaction.JpaTestExtensions; +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 java.io.IOException; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** Tests for {@link google.registry.ui.server.console.ConsoleUserDataAction}. */ +class ConsoleUserDataActionTest { + + private final HttpServletRequest request = mock(HttpServletRequest.class); + private RegistrarPoc testRegistrarPoc; + private static final Gson GSON = RequestModule.provideGson(); + private FakeResponse response = new FakeResponse(); + + @RegisterExtension + final JpaTestExtensions.JpaIntegrationTestExtension jpa = + new JpaTestExtensions.Builder().buildIntegrationTestExtension(); + + @Test + void testSuccess_getContactInfo() throws IOException { + User user = + new User.Builder() + .setEmailAddress("email@email.com") + .setGaiaId("gaiaId") + .setUserRoles(new UserRoles.Builder().setGlobalRole(GlobalRole.FTE).build()) + .build(); + + ConsoleUserDataAction action = + createAction(AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user))); + action.run(); + assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_OK); + Map jsonObject = GSON.fromJson(response.getPayload(), Map.class); + assertThat(jsonObject) + .containsExactly("isAdmin", false, "technicalDocsUrl", "test", "globalRole", "FTE"); + } + + @Test + void testFailure_notAConsoleUser() throws IOException { + ConsoleUserDataAction action = + createAction( + AuthResult.create( + AuthLevel.USER, + UserAuthInfo.create( + new com.google.appengine.api.users.User( + "JohnDoe@theregistrar.com", "theregistrar.com"), + false))); + action.run(); + assertThat(response.getStatus()).isEqualTo(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED); + } + + private ConsoleUserDataAction createAction(AuthResult authResult) throws IOException { + return new ConsoleUserDataAction(authResult, response, "test"); + } +} 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 4e802554d..e0f7fccf9 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 @@ -5,6 +5,7 @@ PATH CLASS METHODS OK AUT /console-api/settings/contacts ContactAction GET,POST n API,LEGACY USER PUBLIC /console-api/settings/security SecurityAction POST n API,LEGACY USER PUBLIC /console-api/settings/whois-fields WhoisRegistrarFieldsAction POST n API,LEGACY USER PUBLIC +/console-api/userdata ConsoleUserDataAction GET n API,LEGACY USER PUBLIC /registrar ConsoleUiAction GET n API,LEGACY NONE PUBLIC /registrar-create ConsoleRegistrarCreatorAction POST,GET n API,LEGACY NONE PUBLIC /registrar-ote-setup ConsoleOteSetupAction POST,GET n API,LEGACY NONE PUBLIC