From a722a4bf65d94c1576a0ff457819967e203c7658 Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Tue, 10 Sep 2024 15:56:01 +0100 Subject: [PATCH 1/4] Added getTokensByLoginId method Signed-off-by: Aashir Siddiqui --- .../authentication/AuthenticationServlet.java | 4 + .../routes/AuthTokensByLoginIdRoute.java | 130 ++++++++++++ .../routes/AuthTokensByLoginIdRouteTest.java | 191 ++++++++++++++++++ .../common/mocks/MockAuthStoreService.java | 14 ++ .../src/main/resources/openapi.yaml | 44 +++- .../framework/api/mocks/MockAuthStore.java | 5 + .../auth/FrameworkAuthStoreService.java | 5 + .../galasa/framework/spi/auth/IAuthStore.java | 9 + .../framework/spi/auth/IAuthStoreService.java | 8 + 9 files changed, 409 insertions(+), 1 deletion(-) create mode 100644 galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java create mode 100644 galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java index 1bb24d2f5..2682fc6de 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java @@ -21,6 +21,7 @@ import dev.galasa.framework.api.authentication.internal.routes.AuthCallbackRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthClientsRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthRoute; +import dev.galasa.framework.api.authentication.internal.routes.AuthTokensByLoginIdRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthTokensDetailsRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthTokensRoute; import dev.galasa.framework.api.common.BaseServlet; @@ -43,6 +44,8 @@ public class AuthenticationServlet extends BaseServlet { private static final long serialVersionUID = 1L; + public static final String QUERY_PARAM_LOGIN_ID = "loginId"; + private Log logger = LogFactory.getLog(getClass()); protected Environment env = new SystemEnvironment(); @@ -69,6 +72,7 @@ public void init() throws ServletException { addRoute(new AuthCallbackRoute(getResponseBuilder(), externalApiServerUrl)); addRoute(new AuthTokensRoute(getResponseBuilder(), oidcProvider, dexGrpcClient, authStoreService, env)); addRoute(new AuthTokensDetailsRoute(getResponseBuilder(), dexGrpcClient, authStoreService)); + addRoute(new AuthTokensByLoginIdRoute(getResponseBuilder(), oidcProvider, dexGrpcClient, authStoreService,env)); logger.info("Galasa Authentication API initialised"); } diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java new file mode 100644 index 000000000..8626775a6 --- /dev/null +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java @@ -0,0 +1,130 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.framework.api.authentication.internal.routes; + +import static dev.galasa.framework.api.common.ServletErrorMessage.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import dev.galasa.framework.api.authentication.AuthenticationServlet; +import dev.galasa.framework.api.authentication.IOidcProvider; +import dev.galasa.framework.api.authentication.internal.DexGrpcClient; +import dev.galasa.framework.api.beans.AuthToken; +import dev.galasa.framework.api.beans.User; +import dev.galasa.framework.api.common.BaseRoute; +import dev.galasa.framework.api.common.Environment; +import dev.galasa.framework.api.common.InternalServletException; +import dev.galasa.framework.api.common.QueryParameters; +import dev.galasa.framework.api.common.ResponseBuilder; +import dev.galasa.framework.api.common.ServletError; +import dev.galasa.framework.spi.FrameworkException; +import dev.galasa.framework.spi.auth.IInternalAuthToken; +import dev.galasa.framework.spi.auth.AuthStoreException; + +import dev.galasa.framework.spi.auth.IAuthStoreService; + + +public class AuthTokensByLoginIdRoute extends BaseRoute{ + + private IAuthStoreService authStoreService; + private IOidcProvider oidcProvider; + private DexGrpcClient dexGrpcClient; + private Environment env; + + // Regex to match /auth/tokens and /auth/tokens/ only + private static final String PATH_PATTERN = "\\/getTokensByLoginId\\/?"; + + public AuthTokensByLoginIdRoute( + ResponseBuilder responseBuilder, + IOidcProvider oidcProvider, + DexGrpcClient dexGrpcClient, + IAuthStoreService authStoreService, + Environment env + ) { + super(responseBuilder, PATH_PATTERN); + this.oidcProvider = oidcProvider; + this.dexGrpcClient = dexGrpcClient; + this.authStoreService = authStoreService; + this.env = env; + } + + /** + * GET requests to /auth/tokens return all the tokens stored in the tokens + * database, sorted by creation date order by default. + */ + @Override + public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters queryParams, + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, FrameworkException { + + logger.info("handleGetRequest() entered"); + + List tokensToReturn = new ArrayList<>(); + try { + // Retrieve all the tokens and put them into a mutable list before sorting them based on their creation time + + validateQueryParam(queryParams, pathInfo); + + List tokens = new ArrayList<>(authStoreService.getTokensByLoginId(queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null))); + + // Convert the token received from the auth store into the token bean that will be returned as JSON + for (IInternalAuthToken token : tokens) { + User user = new User(token.getOwner().getLoginId()); + tokensToReturn.add(new AuthToken( + token.getTokenId(), + token.getDescription(), + token.getCreationTime(), + user) + ); + } + } catch (AuthStoreException e) { + ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); + throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); + } + + return getResponseBuilder().buildResponse(request, response, "application/json", getTokensAsJsonString(tokensToReturn), HttpServletResponse.SC_OK); + } + + private void validateQueryParam(QueryParameters queryParams, String servletPath) throws InternalServletException { + + String loginId = queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null); + + if(loginId == null){ + ServletError error = new ServletError(GAL5400_BAD_REQUEST, servletPath); + throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST); + } + + } + + /** + * Converts a list of authentication tokens into a JSON string + * + * @param tokens the tokens to convert + * @return a JSON representation of the tokens within a "tokens" JSON array + */ + private String getTokensAsJsonString(List tokens) { + JsonArray tokensArray = new JsonArray(); + for (AuthToken token : tokens) { + String tokenJson = gson.toJson(token); + tokensArray.add(JsonParser.parseString(tokenJson)); + } + + JsonObject tokensObj = new JsonObject(); + tokensObj.add("tokens", tokensArray); + + return gson.toJson(tokensObj); + } +} diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java b/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java new file mode 100644 index 000000000..e97f9379b --- /dev/null +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java @@ -0,0 +1,191 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.framework.api.authentication.routes; + +import static org.assertj.core.api.Assertions.*; + +import java.time.Instant; +import java.util.List; +import java.util.HashMap; +import java.util.Collections; +import java.util.Map; + +import javax.servlet.ServletOutputStream; + +import org.junit.Test; + +import dev.galasa.framework.api.authentication.mocks.MockAuthenticationServlet; +import dev.galasa.framework.api.beans.AuthToken; +import dev.galasa.framework.api.beans.User; +import dev.galasa.framework.api.common.BaseServletTest; +import dev.galasa.framework.api.common.InternalUser; +import dev.galasa.framework.api.common.mocks.MockHttpServletRequest; +import dev.galasa.framework.api.common.mocks.MockHttpServletResponse; +import dev.galasa.framework.api.common.mocks.MockInternalAuthToken; +import dev.galasa.framework.api.common.mocks.MockAuthStoreService; +import dev.galasa.framework.spi.auth.IInternalAuthToken; +import dev.galasa.framework.spi.auth.IInternalUser; +import dev.galasa.framework.api.common.mocks.MockFramework; + +public class AuthTokensByLoginIdRouteTest extends BaseServletTest { + + Map headerMap = Map.of("Authorization", "Bearer " + BaseServletTest.DUMMY_JWT); + + @Test + public void testTokenByLoginIdGetRequestWithNullQueryParamReturnsBadRequest() throws Exception { + + // Given... + String requestorLoginId = null; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + List tokens = Collections.emptyList(); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + assertThat(servletResponse.getStatus()).isEqualTo(400); + checkErrorStructure(outStream.toString(), 5400, "GAL5400E", + "Error occurred when trying to execute request '/getTokensByLoginId'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); + } + + @Test + public void testTokenByLoginIdGetRequestWithValidQueryParamReturnsOK() throws Exception { + + // Given... + String requestorLoginId = "admin"; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + User owner = new User(requestorLoginId); + + Instant time1 = Instant.EPOCH; + Instant time2 = Instant.ofEpochSecond(2000); + Instant time3 = Instant.MAX; + + AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, owner); + AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, owner); + AuthToken token3 = new AuthToken("token3", "future creation time", time3, owner); + AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, owner); + + List tokens = List.of( + new MockInternalAuthToken(token1), + new MockInternalAuthToken(token2), + new MockInternalAuthToken(token3), + new MockInternalAuthToken(token4)); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + String output = outStream.toString(); + + assertThat(servletResponse.getStatus()).isEqualTo(200); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(4); + } + + @Test + public void testTokenByLoginIdGetRequestWithValidQueryParamButDifferentOwnersReturnsOK() throws Exception { + + // Given... + String requestorLoginId = "admin"; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + User actualOwner = new User(requestorLoginId); + User someOtherUser = new User("someOtherUser"); + + Instant time1 = Instant.EPOCH; + Instant time2 = Instant.ofEpochSecond(2000); + Instant time3 = Instant.MAX; + + AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, actualOwner); + AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, someOtherUser); + AuthToken token3 = new AuthToken("token3", "future creation time", time3, actualOwner); + AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, someOtherUser); + + List tokens = List.of( + new MockInternalAuthToken(token1), + new MockInternalAuthToken(token2), + new MockInternalAuthToken(token3), + new MockInternalAuthToken(token4)); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + String output = outStream.toString(); + + assertThat(servletResponse.getStatus()).isEqualTo(200); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(getJsonArrayFromJson(output, "tokens")).isNotEmpty(); + assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(2); + } + + @Test + public void testGetAuthTokensByLoginIdWithAuthStoreExceptionThrowsInternalServletException() throws Exception { + // Given... + String tokenId = "id123"; + String description = "test token"; + String clientId = "my-client"; + Instant creationTime = Instant.now(); + IInternalUser owner = new InternalUser("username", "dexId"); + + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { "username" }); + + List tokens = List.of( + new MockInternalAuthToken(tokenId, description, creationTime, owner, clientId) + ); + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + authStoreService.setThrowException(true); + + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams,"/getTokensByLoginId"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + assertThat(servletResponse.getStatus()).isEqualTo(500); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(outStream.toString()).contains("GAL5053E", "Internal server error occurred when retrieving tokens from the auth store", "The auth store could be badly configured or could be experiencing temporary issues"); + } + +} diff --git a/galasa-parent/dev.galasa.framework.api.common/src/testFixtures/java/dev/galasa/framework/api/common/mocks/MockAuthStoreService.java b/galasa-parent/dev.galasa.framework.api.common/src/testFixtures/java/dev/galasa/framework/api/common/mocks/MockAuthStoreService.java index 8eeb05a36..c858d9e06 100644 --- a/galasa-parent/dev.galasa.framework.api.common/src/testFixtures/java/dev/galasa/framework/api/common/mocks/MockAuthStoreService.java +++ b/galasa-parent/dev.galasa.framework.api.common/src/testFixtures/java/dev/galasa/framework/api/common/mocks/MockAuthStoreService.java @@ -86,4 +86,18 @@ public IInternalAuthToken getToken(String tokenId) throws AuthStoreException { } return tokenToReturn; } + + @Override + public List getTokensByLoginId(String loginId) throws AuthStoreException { + if (throwException) { + throwAuthStoreException(); + } + List tokensToReturn = new ArrayList<>(); + for (IInternalAuthToken token : tokens) { + if (token.getOwner().getLoginId().equals(loginId)) { + tokensToReturn.add(token); + } + } + return tokensToReturn; + } } diff --git a/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml b/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml index 0ea38548e..3fd6ff78e 100644 --- a/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml +++ b/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml @@ -63,7 +63,7 @@ paths: missingparametererror: value: error_code: 5400 - error_message: "E: Error occurred when trying to execute request '/user'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." + error_message: "E: Error occured when trying to execute request '/user'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." summary: One or more required query parameters are missing '500': $ref: '#/components/responses/InternalServerError' @@ -284,6 +284,48 @@ paths: error_code: 5000 error_message: "GAL5000E: Error occurred when trying to access the endpoint. Report the problem to your Galasa Ecosystem owner." summary: An Error occurred when trying to access the endpoint + + /auth/getTokensByLoginId: + parameters: + - $ref: '#/components/parameters/ClientApiVersion' + get: + operationId: getTokensByLoginId + summary: Gets all access tokens of a user based on the loginId provided + description: | + Returns an array of access token objects of a user based on their loginId. + tags: + - Authentication API + parameters: + - name: loginId + in: query + description: | + The loginId of the user whose details will be returned. + required: true + schema: + type: string + responses: + '200': + description: Success message returning an array of access tokens. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthTokens' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/APIError' + examples: + missingparametererror: + value: + error_code: 5400 + error_message: "E: Error occured when trying to execute request '/getTokensByLoginId'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." + summary: One or more required query parameters are missing + '401': + $ref: "#/components/responses/Unauthorized" + '500': + $ref: '#/components/responses/InternalServerError' ################################################################################## # Users API diff --git a/galasa-parent/dev.galasa.framework.api/src/test/java/dev/galasa/framework/api/mocks/MockAuthStore.java b/galasa-parent/dev.galasa.framework.api/src/test/java/dev/galasa/framework/api/mocks/MockAuthStore.java index 183540464..4d376b91f 100644 --- a/galasa-parent/dev.galasa.framework.api/src/test/java/dev/galasa/framework/api/mocks/MockAuthStore.java +++ b/galasa-parent/dev.galasa.framework.api/src/test/java/dev/galasa/framework/api/mocks/MockAuthStore.java @@ -20,6 +20,11 @@ public List getTokens() throws AuthStoreException { throw new UnsupportedOperationException("Unimplemented method 'getTokens'"); } + @Override + public List getTokensByLoginId(String loginId) throws AuthStoreException { + throw new UnsupportedOperationException("Unimplemented method 'getTokens'"); + } + @Override public void shutdown() throws AuthStoreException { throw new UnsupportedOperationException("Unimplemented method 'shutdown'"); diff --git a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/internal/auth/FrameworkAuthStoreService.java b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/internal/auth/FrameworkAuthStoreService.java index 09609a94b..a0889b06c 100644 --- a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/internal/auth/FrameworkAuthStoreService.java +++ b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/internal/auth/FrameworkAuthStoreService.java @@ -52,4 +52,9 @@ public void storeToken(String clientId, String description, IInternalUser owner) public void deleteToken(String tokenId) throws AuthStoreException { authStore.deleteToken(tokenId); } + + @Override + public List getTokensByLoginId(String loginId) throws AuthStoreException { + return authStore.getTokensByLoginId(loginId); + } } diff --git a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java index 3d21d4cbb..22337caaa 100644 --- a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java +++ b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java @@ -17,6 +17,15 @@ public interface IAuthStore { */ List getTokens() throws AuthStoreException; + + /** + * Returns a list of all the token records stored in the auth store by login ID. + * + * @return a list of all token records stored in the auth store by login ID. + * @throws AuthStoreException if there is an issue accessing the auth store. + */ + List getTokensByLoginId(String loginId) throws AuthStoreException; + /** * Stores a new token record in the auth store's tokens database. * diff --git a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java index 322464642..858370979 100644 --- a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java +++ b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java @@ -17,6 +17,14 @@ public interface IAuthStoreService { */ List getTokens() throws AuthStoreException; + /** + * Returns a list of all the token records stored in the auth store by login ID. + * + * @return a list of all token records stored in the auth store by login ID. + * @throws AuthStoreException if there is an issue accessing the auth store. + */ + List getTokensByLoginId(String loginId) throws AuthStoreException; + /** * Gets an token record given its ID from the auth store. * From c6028ecb47a97d6fd4585b5505540eb06ffdba8c Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Wed, 11 Sep 2024 16:24:54 +0100 Subject: [PATCH 2/4] Implemented the changes requested Signed-off-by: Aashir Siddiqui --- .../authentication/AuthenticationServlet.java | 2 - .../routes/AuthTokensByLoginIdRoute.java | 130 ------------ .../internal/routes/AuthTokensRoute.java | 125 +++++++++--- .../routes/AuthTokensByLoginIdRouteTest.java | 191 ------------------ .../routes/AuthTokensRouteTest.java | 185 ++++++++++++++++- .../src/main/resources/openapi.yaml | 62 ++---- .../galasa/framework/spi/auth/IAuthStore.java | 2 +- .../framework/spi/auth/IAuthStoreService.java | 2 +- 8 files changed, 305 insertions(+), 394 deletions(-) delete mode 100644 galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java delete mode 100644 galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java index 2682fc6de..714cee2b8 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java @@ -21,7 +21,6 @@ import dev.galasa.framework.api.authentication.internal.routes.AuthCallbackRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthClientsRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthRoute; -import dev.galasa.framework.api.authentication.internal.routes.AuthTokensByLoginIdRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthTokensDetailsRoute; import dev.galasa.framework.api.authentication.internal.routes.AuthTokensRoute; import dev.galasa.framework.api.common.BaseServlet; @@ -72,7 +71,6 @@ public void init() throws ServletException { addRoute(new AuthCallbackRoute(getResponseBuilder(), externalApiServerUrl)); addRoute(new AuthTokensRoute(getResponseBuilder(), oidcProvider, dexGrpcClient, authStoreService, env)); addRoute(new AuthTokensDetailsRoute(getResponseBuilder(), dexGrpcClient, authStoreService)); - addRoute(new AuthTokensByLoginIdRoute(getResponseBuilder(), oidcProvider, dexGrpcClient, authStoreService,env)); logger.info("Galasa Authentication API initialised"); } diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java deleted file mode 100644 index 8626775a6..000000000 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensByLoginIdRoute.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ -package dev.galasa.framework.api.authentication.internal.routes; - -import static dev.galasa.framework.api.common.ServletErrorMessage.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; - -import dev.galasa.framework.api.authentication.AuthenticationServlet; -import dev.galasa.framework.api.authentication.IOidcProvider; -import dev.galasa.framework.api.authentication.internal.DexGrpcClient; -import dev.galasa.framework.api.beans.AuthToken; -import dev.galasa.framework.api.beans.User; -import dev.galasa.framework.api.common.BaseRoute; -import dev.galasa.framework.api.common.Environment; -import dev.galasa.framework.api.common.InternalServletException; -import dev.galasa.framework.api.common.QueryParameters; -import dev.galasa.framework.api.common.ResponseBuilder; -import dev.galasa.framework.api.common.ServletError; -import dev.galasa.framework.spi.FrameworkException; -import dev.galasa.framework.spi.auth.IInternalAuthToken; -import dev.galasa.framework.spi.auth.AuthStoreException; - -import dev.galasa.framework.spi.auth.IAuthStoreService; - - -public class AuthTokensByLoginIdRoute extends BaseRoute{ - - private IAuthStoreService authStoreService; - private IOidcProvider oidcProvider; - private DexGrpcClient dexGrpcClient; - private Environment env; - - // Regex to match /auth/tokens and /auth/tokens/ only - private static final String PATH_PATTERN = "\\/getTokensByLoginId\\/?"; - - public AuthTokensByLoginIdRoute( - ResponseBuilder responseBuilder, - IOidcProvider oidcProvider, - DexGrpcClient dexGrpcClient, - IAuthStoreService authStoreService, - Environment env - ) { - super(responseBuilder, PATH_PATTERN); - this.oidcProvider = oidcProvider; - this.dexGrpcClient = dexGrpcClient; - this.authStoreService = authStoreService; - this.env = env; - } - - /** - * GET requests to /auth/tokens return all the tokens stored in the tokens - * database, sorted by creation date order by default. - */ - @Override - public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters queryParams, - HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException, FrameworkException { - - logger.info("handleGetRequest() entered"); - - List tokensToReturn = new ArrayList<>(); - try { - // Retrieve all the tokens and put them into a mutable list before sorting them based on their creation time - - validateQueryParam(queryParams, pathInfo); - - List tokens = new ArrayList<>(authStoreService.getTokensByLoginId(queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null))); - - // Convert the token received from the auth store into the token bean that will be returned as JSON - for (IInternalAuthToken token : tokens) { - User user = new User(token.getOwner().getLoginId()); - tokensToReturn.add(new AuthToken( - token.getTokenId(), - token.getDescription(), - token.getCreationTime(), - user) - ); - } - } catch (AuthStoreException e) { - ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); - throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); - } - - return getResponseBuilder().buildResponse(request, response, "application/json", getTokensAsJsonString(tokensToReturn), HttpServletResponse.SC_OK); - } - - private void validateQueryParam(QueryParameters queryParams, String servletPath) throws InternalServletException { - - String loginId = queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null); - - if(loginId == null){ - ServletError error = new ServletError(GAL5400_BAD_REQUEST, servletPath); - throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST); - } - - } - - /** - * Converts a list of authentication tokens into a JSON string - * - * @param tokens the tokens to convert - * @return a JSON representation of the tokens within a "tokens" JSON array - */ - private String getTokensAsJsonString(List tokens) { - JsonArray tokensArray = new JsonArray(); - for (AuthToken token : tokens) { - String tokenJson = gson.toJson(token); - tokensArray.add(JsonParser.parseString(tokenJson)); - } - - JsonObject tokensObj = new JsonObject(); - tokensObj.add("tokens", tokensArray); - - return gson.toJson(tokensObj); - } -} diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java index 45725e3e3..b84012d2d 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java @@ -23,6 +23,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import dev.galasa.framework.api.authentication.AuthenticationServlet; import dev.galasa.framework.api.authentication.IOidcProvider; import dev.galasa.framework.api.authentication.internal.DexGrpcClient; import dev.galasa.framework.api.authentication.internal.TokenPayloadValidator; @@ -51,7 +52,7 @@ public class AuthTokensRoute extends BaseRoute { private DexGrpcClient dexGrpcClient; private Environment env; - private static final String ID_TOKEN_KEY = "id_token"; + private static final String ID_TOKEN_KEY = "id_token"; private static final String REFRESH_TOKEN_KEY = "refresh_token"; // Regex to match /auth/tokens and /auth/tokens/ only @@ -60,12 +61,11 @@ public class AuthTokensRoute extends BaseRoute { private static final IBeanValidator validator = new TokenPayloadValidator(); public AuthTokensRoute( - ResponseBuilder responseBuilder, - IOidcProvider oidcProvider, - DexGrpcClient dexGrpcClient, - IAuthStoreService authStoreService, - Environment env - ) { + ResponseBuilder responseBuilder, + IOidcProvider oidcProvider, + DexGrpcClient dexGrpcClient, + IAuthStoreService authStoreService, + Environment env) { super(responseBuilder, PATH_PATTERN); this.oidcProvider = oidcProvider; this.dexGrpcClient = dexGrpcClient; @@ -76,6 +76,8 @@ public AuthTokensRoute( /** * GET requests to /auth/tokens return all the tokens stored in the tokens * database, sorted by creation date order by default. + * This endpoint takes an optional query paramater 'loginId' for e.g loginId=admin + * Passing it returns a filtered list of token records stored in the auth store that matches the given login ID */ @Override public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters queryParams, @@ -83,29 +85,67 @@ public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters que throws ServletException, IOException, FrameworkException { logger.info("handleGetRequest() entered"); + + List tokensToReturn = new ArrayList<>(); + String loginId = queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null); + + if(queryParams.checkAtLeastOneQueryParameterPresent("loginId")){ + validateLoginId(loginId, pathInfo); + } + + if(loginId == null){ + tokensToReturn = handleGetAllTokens(); + } + else{ + tokensToReturn = handleGetTokensByLoginId(loginId); + } + + return getResponseBuilder().buildResponse(request, response, "application/json", + getTokensAsJsonString(tokensToReturn), HttpServletResponse.SC_OK); + } + + public List handleGetAllTokens() throws ServletException, IOException, FrameworkException{ List tokensToReturn = new ArrayList<>(); try { - // Retrieve all the tokens and put them into a mutable list before sorting them based on their creation time + // Retrieve all the tokens and put them into a mutable list before sorting them + // based on their creation time List tokens = new ArrayList<>(authStoreService.getTokens()); Collections.sort(tokens, Comparator.comparing(IInternalAuthToken::getCreationTime)); - // Convert the token received from the auth store into the token bean that will be returned as JSON - for (IInternalAuthToken token : tokens) { - User user = new User(token.getOwner().getLoginId()); - tokensToReturn.add(new AuthToken( - token.getTokenId(), - token.getDescription(), - token.getCreationTime(), - user) - ); - } + // Convert the token received from the auth store into the token bean that will + // be returned as JSON + tokensToReturn = convertAuthStoreTokenIntoTokenBean(tokens); + } catch (AuthStoreException e) { ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } - return getResponseBuilder().buildResponse(request, response, "application/json", getTokensAsJsonString(tokensToReturn), HttpServletResponse.SC_OK); + return tokensToReturn; + + } + + public List handleGetTokensByLoginId(String loginId) + throws ServletException, IOException, FrameworkException { + + logger.info("fetching access tokens by loginId"); + + List tokensToReturn = new ArrayList<>(); + + try{ + List tokens = new ArrayList<>(authStoreService.getTokensByLoginId(loginId)); + + // Convert the token received from the auth store into the token bean that will + // be returned as JSON + tokensToReturn = convertAuthStoreTokenIntoTokenBean(tokens); + + }catch(AuthStoreException e){ + ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); + throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); + } + + return tokensToReturn; } /** @@ -114,7 +154,8 @@ public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters que */ @Override public HttpServletResponse handlePostRequest(String pathInfo, QueryParameters queryParameters, - HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, FrameworkException { + HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException, FrameworkException { logger.info("AuthRoute: handlePostRequest() entered."); @@ -128,14 +169,16 @@ public HttpServletResponse handlePostRequest(String pathInfo, QueryParameters qu JsonObject tokenResponseBodyJson = sendTokenPost(requestPayload); // Return the JWT and refresh token as the servlet's response - if (tokenResponseBodyJson != null && tokenResponseBodyJson.has(ID_TOKEN_KEY) && tokenResponseBodyJson.has(REFRESH_TOKEN_KEY)) { + if (tokenResponseBodyJson != null && tokenResponseBodyJson.has(ID_TOKEN_KEY) + && tokenResponseBodyJson.has(REFRESH_TOKEN_KEY)) { logger.info("Bearer and refresh tokens successfully received from issuer."); String jwt = tokenResponseBodyJson.get(ID_TOKEN_KEY).getAsString(); responseJson.addProperty("jwt", jwt); responseJson.addProperty(REFRESH_TOKEN_KEY, tokenResponseBodyJson.get(REFRESH_TOKEN_KEY).getAsString()); - // If we're refreshing an existing token, then we don't want to create a new entry in the tokens database. + // If we're refreshing an existing token, then we don't want to create a new + // entry in the tokens database. // We only want to store tokens in the tokens database when they are created. String tokenDescription = requestPayload.getDescription(); if (requestPayload.getRefreshToken() == null && tokenDescription != null) { @@ -156,7 +199,8 @@ public HttpServletResponse handlePostRequest(String pathInfo, QueryParameters qu throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } - return getResponseBuilder().buildResponse(request, response, "application/json", gson.toJson(responseJson), HttpServletResponse.SC_OK); + return getResponseBuilder().buildResponse(request, response, "application/json", gson.toJson(responseJson), + HttpServletResponse.SC_OK); } /** @@ -202,7 +246,8 @@ private JsonObject sendTokenPost(TokenPayload requestBodyJson) if (refreshToken != null) { tokenResponse = oidcProvider.sendTokenPost(clientId, clientSecret, refreshToken); } else { - tokenResponse = oidcProvider.sendTokenPost(clientId, clientSecret, requestBodyJson.getCode(), AuthCallbackRoute.getExternalAuthCallbackUrl()); + tokenResponse = oidcProvider.sendTokenPost(clientId, clientSecret, requestBodyJson.getCode(), + AuthCallbackRoute.getExternalAuthCallbackUrl()); } if (tokenResponse != null) { @@ -215,8 +260,9 @@ private JsonObject sendTokenPost(TokenPayload requestBodyJson) /** * Records a new Galasa token in the auth store. * - * @param clientId the ID of the client that a user has authenticated with - * @param jwt the JWT that was returned after authenticating with the client, identifying the user + * @param clientId the ID of the client that a user has authenticated with + * @param jwt the JWT that was returned after authenticating with the + * client, identifying the user * @param description the description of the Galasa token provided by the user * @throws InternalServletException */ @@ -233,4 +279,31 @@ private void addTokenToAuthStore(String clientId, String jwt, String description } logger.info("Stored token record in the auth store OK"); } + + private List convertAuthStoreTokenIntoTokenBean(List authStoreTokens){ + + List tokensToReturn = new ArrayList<>(); + + for (IInternalAuthToken token : authStoreTokens) { + + User user = new User(token.getOwner().getLoginId()); + tokensToReturn.add(new AuthToken( + token.getTokenId(), + token.getDescription(), + token.getCreationTime(), + user)); + } + + return tokensToReturn; + + } + + private void validateLoginId(String loginId, String servletPath) throws InternalServletException { + + if (loginId ==null || loginId.trim() == null) { + ServletError error = new ServletError(GAL5400_BAD_REQUEST, servletPath); + throw new InternalServletException(error, HttpServletResponse.SC_BAD_REQUEST); + } + + } } diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java b/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java deleted file mode 100644 index e97f9379b..000000000 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensByLoginIdRouteTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright contributors to the Galasa project - * - * SPDX-License-Identifier: EPL-2.0 - */ -package dev.galasa.framework.api.authentication.routes; - -import static org.assertj.core.api.Assertions.*; - -import java.time.Instant; -import java.util.List; -import java.util.HashMap; -import java.util.Collections; -import java.util.Map; - -import javax.servlet.ServletOutputStream; - -import org.junit.Test; - -import dev.galasa.framework.api.authentication.mocks.MockAuthenticationServlet; -import dev.galasa.framework.api.beans.AuthToken; -import dev.galasa.framework.api.beans.User; -import dev.galasa.framework.api.common.BaseServletTest; -import dev.galasa.framework.api.common.InternalUser; -import dev.galasa.framework.api.common.mocks.MockHttpServletRequest; -import dev.galasa.framework.api.common.mocks.MockHttpServletResponse; -import dev.galasa.framework.api.common.mocks.MockInternalAuthToken; -import dev.galasa.framework.api.common.mocks.MockAuthStoreService; -import dev.galasa.framework.spi.auth.IInternalAuthToken; -import dev.galasa.framework.spi.auth.IInternalUser; -import dev.galasa.framework.api.common.mocks.MockFramework; - -public class AuthTokensByLoginIdRouteTest extends BaseServletTest { - - Map headerMap = Map.of("Authorization", "Bearer " + BaseServletTest.DUMMY_JWT); - - @Test - public void testTokenByLoginIdGetRequestWithNullQueryParamReturnsBadRequest() throws Exception { - - // Given... - String requestorLoginId = null; - Map queryParams = new HashMap<>(); - - queryParams.put("loginId", new String[] { requestorLoginId }); - - List tokens = Collections.emptyList(); - - MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); - MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); - - MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); - MockHttpServletResponse servletResponse = new MockHttpServletResponse(); - ServletOutputStream outStream = servletResponse.getOutputStream(); - - // When... - servlet.init(); - servlet.doGet(mockRequest, servletResponse); - - assertThat(servletResponse.getStatus()).isEqualTo(400); - checkErrorStructure(outStream.toString(), 5400, "GAL5400E", - "Error occurred when trying to execute request '/getTokensByLoginId'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); - } - - @Test - public void testTokenByLoginIdGetRequestWithValidQueryParamReturnsOK() throws Exception { - - // Given... - String requestorLoginId = "admin"; - Map queryParams = new HashMap<>(); - - queryParams.put("loginId", new String[] { requestorLoginId }); - - User owner = new User(requestorLoginId); - - Instant time1 = Instant.EPOCH; - Instant time2 = Instant.ofEpochSecond(2000); - Instant time3 = Instant.MAX; - - AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, owner); - AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, owner); - AuthToken token3 = new AuthToken("token3", "future creation time", time3, owner); - AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, owner); - - List tokens = List.of( - new MockInternalAuthToken(token1), - new MockInternalAuthToken(token2), - new MockInternalAuthToken(token3), - new MockInternalAuthToken(token4)); - - MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); - MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); - - MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); - MockHttpServletResponse servletResponse = new MockHttpServletResponse(); - ServletOutputStream outStream = servletResponse.getOutputStream(); - - // When... - servlet.init(); - servlet.doGet(mockRequest, servletResponse); - - // Then... - String output = outStream.toString(); - - assertThat(servletResponse.getStatus()).isEqualTo(200); - assertThat(servletResponse.getContentType()).isEqualTo("application/json"); - assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(4); - } - - @Test - public void testTokenByLoginIdGetRequestWithValidQueryParamButDifferentOwnersReturnsOK() throws Exception { - - // Given... - String requestorLoginId = "admin"; - Map queryParams = new HashMap<>(); - - queryParams.put("loginId", new String[] { requestorLoginId }); - - User actualOwner = new User(requestorLoginId); - User someOtherUser = new User("someOtherUser"); - - Instant time1 = Instant.EPOCH; - Instant time2 = Instant.ofEpochSecond(2000); - Instant time3 = Instant.MAX; - - AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, actualOwner); - AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, someOtherUser); - AuthToken token3 = new AuthToken("token3", "future creation time", time3, actualOwner); - AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, someOtherUser); - - List tokens = List.of( - new MockInternalAuthToken(token1), - new MockInternalAuthToken(token2), - new MockInternalAuthToken(token3), - new MockInternalAuthToken(token4)); - - MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); - MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); - - MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/getTokensByLoginId"); - MockHttpServletResponse servletResponse = new MockHttpServletResponse(); - ServletOutputStream outStream = servletResponse.getOutputStream(); - - // When... - servlet.init(); - servlet.doGet(mockRequest, servletResponse); - - // Then... - String output = outStream.toString(); - - assertThat(servletResponse.getStatus()).isEqualTo(200); - assertThat(servletResponse.getContentType()).isEqualTo("application/json"); - assertThat(getJsonArrayFromJson(output, "tokens")).isNotEmpty(); - assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(2); - } - - @Test - public void testGetAuthTokensByLoginIdWithAuthStoreExceptionThrowsInternalServletException() throws Exception { - // Given... - String tokenId = "id123"; - String description = "test token"; - String clientId = "my-client"; - Instant creationTime = Instant.now(); - IInternalUser owner = new InternalUser("username", "dexId"); - - Map queryParams = new HashMap<>(); - - queryParams.put("loginId", new String[] { "username" }); - - List tokens = List.of( - new MockInternalAuthToken(tokenId, description, creationTime, owner, clientId) - ); - MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); - authStoreService.setThrowException(true); - - MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); - - MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams,"/getTokensByLoginId"); - MockHttpServletResponse servletResponse = new MockHttpServletResponse(); - ServletOutputStream outStream = servletResponse.getOutputStream(); - - // When... - servlet.init(); - servlet.doGet(mockRequest, servletResponse); - - // Then... - assertThat(servletResponse.getStatus()).isEqualTo(500); - assertThat(servletResponse.getContentType()).isEqualTo("application/json"); - assertThat(outStream.toString()).contains("GAL5053E", "Internal server error occurred when retrieving tokens from the auth store", "The auth store could be badly configured or could be experiencing temporary issues"); - } - -} diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensRouteTest.java b/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensRouteTest.java index f8e199c66..bcb1a34e0 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensRouteTest.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/test/java/dev/galasa/framework/api/authentication/routes/AuthTokensRouteTest.java @@ -11,6 +11,8 @@ import java.time.Instant; import java.util.List; import java.util.Map; +import java.util.HashMap; +import java.util.Collections; import java.util.regex.Pattern; import javax.servlet.ServletOutputStream; @@ -232,6 +234,187 @@ public void testGetAuthTokensWithAuthStoreExceptionThrowsInternalServletExceptio assertThat(outStream.toString()).contains("GAL5053E", "Internal server error occurred when retrieving tokens from the auth store", "The auth store could be badly configured or could be experiencing temporary issues"); } + @Test + public void testTokenByLoginIdGetRequestWithNullLoginIdReturnsBadRequest() throws Exception { + + // Given... + String requestorLoginId = " "; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + List tokens = Collections.emptyList(); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/tokens"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + assertThat(servletResponse.getStatus()).isEqualTo(400); + checkErrorStructure(outStream.toString(), 5400, "GAL5400E", + "Error occurred when trying to execute request '/tokens'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); + } + + @Test + public void testTokenByLoginIdGetRequestWithBlankLoginIdReturnsBadRequest() throws Exception { + + // Given... + String requestorLoginId = " "; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + List tokens = Collections.emptyList(); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/tokens"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + assertThat(servletResponse.getStatus()).isEqualTo(400); + checkErrorStructure(outStream.toString(), 5400, "GAL5400E", + "Error occurred when trying to execute request '/tokens'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); + } + + @Test + public void testTokenByLoginIdGetRequestWithValidLoginIdReturnsOK() throws Exception { + + // Given... + String requestorLoginId = "admin"; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + User owner = new User(requestorLoginId); + + Instant time1 = Instant.EPOCH; + Instant time2 = Instant.ofEpochSecond(2000); + Instant time3 = Instant.MAX; + + AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, owner); + AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, owner); + AuthToken token3 = new AuthToken("token3", "future creation time", time3, owner); + AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, owner); + + List tokens = List.of( + new MockInternalAuthToken(token1), + new MockInternalAuthToken(token2), + new MockInternalAuthToken(token3), + new MockInternalAuthToken(token4)); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/tokens"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + String output = outStream.toString(); + + assertThat(servletResponse.getStatus()).isEqualTo(200); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(4); + } + + @Test + public void testTokenByLoginIdGetRequestWithValidLoginIdButDifferentOwnersReturnsOK() throws Exception { + + // Given... + String requestorLoginId = "admin"; + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { requestorLoginId }); + + User actualOwner = new User(requestorLoginId); + User someOtherUser = new User("someOtherUser"); + + Instant time1 = Instant.EPOCH; + Instant time2 = Instant.ofEpochSecond(2000); + Instant time3 = Instant.MAX; + + AuthToken token1 = new AuthToken("token1", "creation time after epoch", time2, actualOwner); + AuthToken token2 = new AuthToken("token2", "epoch creation time", time1, someOtherUser); + AuthToken token3 = new AuthToken("token3", "future creation time", time3, actualOwner); + AuthToken token4 = new AuthToken("token4", "creation time after epoch, same as token1", time2, someOtherUser); + + List tokens = List.of( + new MockInternalAuthToken(token1), + new MockInternalAuthToken(token2), + new MockInternalAuthToken(token3), + new MockInternalAuthToken(token4)); + + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams, "/tokens"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + String output = outStream.toString(); + + assertThat(servletResponse.getStatus()).isEqualTo(200); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(getJsonArrayFromJson(output, "tokens")).isNotEmpty(); + assertThat(getJsonArrayFromJson(output, "tokens")).hasSize(2); + } + + @Test + public void testGetAuthTokensByLoginIdWithAuthStoreExceptionThrowsInternalServletException() throws Exception { + // Given... + String tokenId = "id123"; + String description = "test token"; + String clientId = "my-client"; + Instant creationTime = Instant.now(); + IInternalUser owner = new InternalUser("username", "dexId"); + + Map queryParams = new HashMap<>(); + + queryParams.put("loginId", new String[] { "username" }); + + List tokens = List.of( + new MockInternalAuthToken(tokenId, description, creationTime, owner, clientId) + ); + MockAuthStoreService authStoreService = new MockAuthStoreService(tokens); + authStoreService.setThrowException(true); + + MockAuthenticationServlet servlet = new MockAuthenticationServlet(new MockFramework(authStoreService)); + + MockHttpServletRequest mockRequest = new MockHttpServletRequest(queryParams,"/tokens"); + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + ServletOutputStream outStream = servletResponse.getOutputStream(); + + // When... + servlet.init(); + servlet.doGet(mockRequest, servletResponse); + + // Then... + assertThat(servletResponse.getStatus()).isEqualTo(500); + assertThat(servletResponse.getContentType()).isEqualTo("application/json"); + assertThat(outStream.toString()).contains("GAL5053E", "Internal server error occurred when retrieving tokens from the auth store", "The auth store could be badly configured or could be experiencing temporary issues"); + } + @Test public void testGetAuthTokensReturnsMultipleTokensOrderedByCreationTimeAscending() throws Exception { // Given... @@ -271,7 +454,7 @@ public void testGetAuthTokensReturnsMultipleTokensOrderedByCreationTimeAscending assertThat(servletResponse.getStatus()).isEqualTo(200); assertThat(servletResponse.getContentType()).isEqualTo("application/json"); - checkOrderMatches(expectedTokenOrder, getJsonArrayFromJson(output, "tokens")); + // checkOrderMatches(expectedTokenOrder, getJsonArrayFromJson(output, "tokens")); } @Test diff --git a/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml b/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml index 3fd6ff78e..a58e62200 100644 --- a/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml +++ b/galasa-parent/dev.galasa.framework.api.openapi/src/main/resources/openapi.yaml @@ -63,7 +63,7 @@ paths: missingparametererror: value: error_code: 5400 - error_message: "E: Error occured when trying to execute request '/user'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." + error_message: "E: Error occurred when trying to execute request '/user'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." summary: One or more required query parameters are missing '500': $ref: '#/components/responses/InternalServerError' @@ -183,6 +183,14 @@ paths: in the 'Authorization' header (e.g. 'Authorization: Bearer '). tags: - Authentication API + parameters: + - name: loginId + in: query + description: | + The loginId of the user whose details will be returned. + required: false + schema: + type: string responses: '200': description: Returns a JSON Object containing the list of tokens @@ -190,6 +198,17 @@ paths: application/json: schema: $ref: '#/components/schemas/AuthTokens' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/APIError' + examples: + missingparametererror: + value: + error_code: 5400 + error_message: "E: Error occured when trying to execute request '/tokens'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." '401': $ref: "#/components/responses/Unauthorized" '500': @@ -285,47 +304,6 @@ paths: error_message: "GAL5000E: Error occurred when trying to access the endpoint. Report the problem to your Galasa Ecosystem owner." summary: An Error occurred when trying to access the endpoint - /auth/getTokensByLoginId: - parameters: - - $ref: '#/components/parameters/ClientApiVersion' - get: - operationId: getTokensByLoginId - summary: Gets all access tokens of a user based on the loginId provided - description: | - Returns an array of access token objects of a user based on their loginId. - tags: - - Authentication API - parameters: - - name: loginId - in: query - description: | - The loginId of the user whose details will be returned. - required: true - schema: - type: string - responses: - '200': - description: Success message returning an array of access tokens. - content: - application/json: - schema: - $ref: '#/components/schemas/AuthTokens' - '400': - description: Bad Request - content: - application/json: - schema: - $ref: '#/components/schemas/APIError' - examples: - missingparametererror: - value: - error_code: 5400 - error_message: "E: Error occured when trying to execute request '/getTokensByLoginId'. Please check your request parameters or report the problem to your Galasa Ecosystem owner." - summary: One or more required query parameters are missing - '401': - $ref: "#/components/responses/Unauthorized" - '500': - $ref: '#/components/responses/InternalServerError' ################################################################################## # Users API diff --git a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java index 22337caaa..2faa72c05 100644 --- a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java +++ b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStore.java @@ -19,7 +19,7 @@ public interface IAuthStore { /** - * Returns a list of all the token records stored in the auth store by login ID. + * Returns a list of token records stored in the auth store that match a given login ID. * * @return a list of all token records stored in the auth store by login ID. * @throws AuthStoreException if there is an issue accessing the auth store. diff --git a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java index 858370979..c3398b901 100644 --- a/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java +++ b/galasa-parent/dev.galasa.framework/src/main/java/dev/galasa/framework/spi/auth/IAuthStoreService.java @@ -18,7 +18,7 @@ public interface IAuthStoreService { List getTokens() throws AuthStoreException; /** - * Returns a list of all the token records stored in the auth store by login ID. + * Returns a list of token records stored in the auth store that match a given login ID. * * @return a list of all token records stored in the auth store by login ID. * @throws AuthStoreException if there is an issue accessing the auth store. From 767f83404f62ac3179f106675caca4a421b1cf38 Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Thu, 12 Sep 2024 16:28:05 +0100 Subject: [PATCH 3/4] Refactored code and implemented changes requested Signed-off-by: Aashir Siddiqui --- .../authentication/AuthenticationServlet.java | 2 - .../internal/routes/AuthTokensRoute.java | 71 +++++++++---------- .../routes/AuthTokensRouteTest.java | 12 ++-- .../framework/api/common/QueryParameters.java | 6 ++ .../api/common/ServletErrorMessage.java | 1 + 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java index 714cee2b8..1bb24d2f5 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/AuthenticationServlet.java @@ -43,8 +43,6 @@ public class AuthenticationServlet extends BaseServlet { private static final long serialVersionUID = 1L; - public static final String QUERY_PARAM_LOGIN_ID = "loginId"; - private Log logger = LogFactory.getLog(getClass()); protected Environment env = new SystemEnvironment(); diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java index b84012d2d..62182b956 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java @@ -23,7 +23,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import dev.galasa.framework.api.authentication.AuthenticationServlet; import dev.galasa.framework.api.authentication.IOidcProvider; import dev.galasa.framework.api.authentication.internal.DexGrpcClient; import dev.galasa.framework.api.authentication.internal.TokenPayloadValidator; @@ -54,6 +53,7 @@ public class AuthTokensRoute extends BaseRoute { private static final String ID_TOKEN_KEY = "id_token"; private static final String REFRESH_TOKEN_KEY = "refresh_token"; + public static final String QUERY_PARAM_LOGIN_ID = "loginId"; // Regex to match /auth/tokens and /auth/tokens/ only private static final String PATH_PATTERN = "\\/tokens\\/?"; @@ -76,76 +76,73 @@ public AuthTokensRoute( /** * GET requests to /auth/tokens return all the tokens stored in the tokens * database, sorted by creation date order by default. - * This endpoint takes an optional query paramater 'loginId' for e.g loginId=admin - * Passing it returns a filtered list of token records stored in the auth store that matches the given login ID + * This endpoint takes an optional query parameter 'loginId' for e.g + * loginId=admin + * Passing it returns a filtered list of token records stored in the auth store + * that matches the given login ID */ @Override public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters queryParams, HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException, FrameworkException { + throws FrameworkException { logger.info("handleGetRequest() entered"); - - List tokensToReturn = new ArrayList<>(); - String loginId = queryParams.getSingleString(AuthenticationServlet.QUERY_PARAM_LOGIN_ID, null); - - if(queryParams.checkAtLeastOneQueryParameterPresent("loginId")){ - validateLoginId(loginId, pathInfo); - } - if(loginId == null){ - tokensToReturn = handleGetAllTokens(); - } - else{ - tokensToReturn = handleGetTokensByLoginId(loginId); + List authTokensFromAuthStore = new ArrayList<>(); + + if (queryParams.isParameterPresent(QUERY_PARAM_LOGIN_ID)) { + + String loginId = queryParams.getSingleString(QUERY_PARAM_LOGIN_ID, null); + validateLoginId(loginId, pathInfo); + authTokensFromAuthStore = getTokensByLoginId(loginId); + + } else { + authTokensFromAuthStore = getAllTokens(); } + // Convert the token received from the auth store into the token bean that will + // be returned as JSON + ListtokensToReturn = convertAuthStoreTokenIntoTokenBeans(authTokensFromAuthStore); + return getResponseBuilder().buildResponse(request, response, "application/json", getTokensAsJsonString(tokensToReturn), HttpServletResponse.SC_OK); } - public List handleGetAllTokens() throws ServletException, IOException, FrameworkException{ + private List getAllTokens() throws FrameworkException { - List tokensToReturn = new ArrayList<>(); try { // Retrieve all the tokens and put them into a mutable list before sorting them // based on their creation time List tokens = new ArrayList<>(authStoreService.getTokens()); Collections.sort(tokens, Comparator.comparing(IInternalAuthToken::getCreationTime)); - // Convert the token received from the auth store into the token bean that will - // be returned as JSON - tokensToReturn = convertAuthStoreTokenIntoTokenBean(tokens); + return tokens; } catch (AuthStoreException e) { ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } - return tokensToReturn; - } - public List handleGetTokensByLoginId(String loginId) - throws ServletException, IOException, FrameworkException { + public List getTokensByLoginId(String loginId) + throws FrameworkException { logger.info("fetching access tokens by loginId"); - List tokensToReturn = new ArrayList<>(); + try { - try{ List tokens = new ArrayList<>(authStoreService.getTokensByLoginId(loginId)); + Collections.sort(tokens, Comparator.comparing(IInternalAuthToken::getCreationTime)); - // Convert the token received from the auth store into the token bean that will - // be returned as JSON - tokensToReturn = convertAuthStoreTokenIntoTokenBean(tokens); - - }catch(AuthStoreException e){ + logger.info("Access tokens by loginId fetched from auth store"); + return tokens; + + } catch (AuthStoreException e) { ServletError error = new ServletError(GAL5053_FAILED_TO_RETRIEVE_TOKENS); throw new InternalServletException(error, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } - return tokensToReturn; } /** @@ -280,10 +277,10 @@ private void addTokenToAuthStore(String clientId, String jwt, String description logger.info("Stored token record in the auth store OK"); } - private List convertAuthStoreTokenIntoTokenBean(List authStoreTokens){ + private List convertAuthStoreTokenIntoTokenBeans(List authStoreTokens) { List tokensToReturn = new ArrayList<>(); - + for (IInternalAuthToken token : authStoreTokens) { User user = new User(token.getOwner().getLoginId()); @@ -300,8 +297,8 @@ private List convertAuthStoreTokenIntoTokenBean(List queryParams = new HashMap<>(); queryParams.put("loginId", new String[] { requestorLoginId }); @@ -257,8 +257,8 @@ public void testTokenByLoginIdGetRequestWithNullLoginIdReturnsBadRequest() throw servlet.doGet(mockRequest, servletResponse); assertThat(servletResponse.getStatus()).isEqualTo(400); - checkErrorStructure(outStream.toString(), 5400, "GAL5400E", - "Error occurred when trying to execute request '/tokens'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); + checkErrorStructure(outStream.toString(), 5057, "GAL5057E", + "Failed to validate loginId. This could be because loginId is null or an empty string. Please check the loginId in the query paramaters provided."); } @Test @@ -284,8 +284,8 @@ public void testTokenByLoginIdGetRequestWithBlankLoginIdReturnsBadRequest() thro servlet.doGet(mockRequest, servletResponse); assertThat(servletResponse.getStatus()).isEqualTo(400); - checkErrorStructure(outStream.toString(), 5400, "GAL5400E", - "Error occurred when trying to execute request '/tokens'. Please check your request parameters or report the problem to your Galasa Ecosystem owner."); + checkErrorStructure(outStream.toString(), 5057, "GAL5057E", + "Failed to validate loginId. This could be because loginId is null or an empty string. Please check the loginId in the query paramaters provided."); } @Test @@ -454,7 +454,7 @@ public void testGetAuthTokensReturnsMultipleTokensOrderedByCreationTimeAscending assertThat(servletResponse.getStatus()).isEqualTo(200); assertThat(servletResponse.getContentType()).isEqualTo("application/json"); - // checkOrderMatches(expectedTokenOrder, getJsonArrayFromJson(output, "tokens")); + checkOrderMatches(expectedTokenOrder, getJsonArrayFromJson(output, "tokens")); } @Test diff --git a/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/QueryParameters.java b/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/QueryParameters.java index 314695b2e..5fa939d46 100644 --- a/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/QueryParameters.java +++ b/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/QueryParameters.java @@ -150,6 +150,12 @@ public Instant getSingleInstant(String queryParameterName, Instant defaultValue) return returnedValue; } + public boolean isParameterPresent(String queryParameter) { + return params.containsKey(queryParameter) + && params.get(queryParameter) != null + && params.get(queryParameter)[0] != ""; + } + public boolean checkAtLeastOneQueryParameterPresent(String... queryParameters ) throws InternalServletException { // This function will return false when none of the parameters provided are in the query boolean result = false; diff --git a/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/ServletErrorMessage.java b/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/ServletErrorMessage.java index 7d862860d..56f1dc9be 100644 --- a/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/ServletErrorMessage.java +++ b/galasa-parent/dev.galasa.framework.api.common/src/main/java/dev/galasa/framework/api/common/ServletErrorMessage.java @@ -106,6 +106,7 @@ public enum ServletErrorMessage { GAL5064_FAILED_TO_REVOKE_TOKEN (5064, "E: Failed to revoke the token with the given ID. Please ensure that you have provided a valid ID representing an existing auth token in your request and try again"), GAL5065_FAILED_TO_GET_TOKEN_ID_FROM_URL (5065, "E: Failed to retrieve a token ID from the request path. Please ensure that you have provided a valid ID representing an existing auth token in your request and try again"), GAL5066_ERROR_NO_SUCH_TOKEN_EXISTS (5066, "E: No such token with the given ID exists. Please ensure that you have provided a valid ID representing an existing auth token in your request and try again"), + GAL5067_ERROR_MALFORMED_LOGINID (5057, "E: Failed to validate loginId. This could be because loginId is null or an empty string. Please check the loginId in the query paramaters provided."), // OpenAPI Servlet... GAL5071_FAILED_TO_PARSE_YAML_INTO_JSON (5071, "E: Internal server error. Failed to convert OpenAPI specification from YAML into JSON. Report the problem to your Galasa Ecosystem owner"), From 971ab7f5c8ef0d7f47e99ef5c1da49e60bb0ac07 Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Thu, 12 Sep 2024 16:35:47 +0100 Subject: [PATCH 4/4] Changed error message Signed-off-by: Aashir Siddiqui --- .../api/authentication/internal/routes/AuthTokensRoute.java | 4 ++-- .../api/authentication/routes/AuthTokensRouteTest.java | 4 ++-- .../dev/galasa/framework/api/common/ServletErrorMessage.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java index 62182b956..2a1de0dd3 100644 --- a/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java +++ b/galasa-parent/dev.galasa.framework.api.authentication/src/main/java/dev/galasa/framework/api/authentication/internal/routes/AuthTokensRoute.java @@ -95,7 +95,7 @@ public HttpServletResponse handleGetRequest(String pathInfo, QueryParameters que String loginId = queryParams.getSingleString(QUERY_PARAM_LOGIN_ID, null); validateLoginId(loginId, pathInfo); authTokensFromAuthStore = getTokensByLoginId(loginId); - + } else { authTokensFromAuthStore = getAllTokens(); } @@ -298,7 +298,7 @@ private List convertAuthStoreTokenIntoTokenBeans(List