From fb912cff7d315f0af3a1a3d787f0d6b6feb826f7 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:03:29 +0200 Subject: [PATCH 01/29] fix coverity issues in v3 Signed-off-by: sj895092 --- .../src/main/java/org/zowe/apiml/util/UrlUtils.java | 3 +-- .../apiml/gateway/conformance/OpenApiV2Validator.java | 2 +- .../apiml/zaas/security/config/CompoundAuthProvider.java | 5 ++++- .../security/service/token/ApimlAccessTokenProvider.java | 8 ++++++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/common-service-core/src/main/java/org/zowe/apiml/util/UrlUtils.java b/common-service-core/src/main/java/org/zowe/apiml/util/UrlUtils.java index d1ade2e026..307b1aa7db 100644 --- a/common-service-core/src/main/java/org/zowe/apiml/util/UrlUtils.java +++ b/common-service-core/src/main/java/org/zowe/apiml/util/UrlUtils.java @@ -40,9 +40,8 @@ public String getEncodedUrl(String url) { if (url != null) { return url.replaceAll("\\W", "-"); } else { - SecureRandom random = new SecureRandom(); byte[] bytes = new byte[20]; - random.nextBytes(bytes); + new SecureRandom().nextBytes(bytes); return Arrays.toString(bytes); } } diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java index 47b5d39610..ae9ad03098 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java @@ -55,7 +55,7 @@ private HashMap> getValidResponses(Path value) { HashMap> result = new HashMap<>(); for (HttpMethod httpMethod : getMethod(value)) { Map responseMap = value.getOperationMap().get(convertSpringHttpToSwagger(httpMethod)).getResponses(); - if ( !responseMap.isEmpty()) { + if ( responseMap != null && !responseMap.isEmpty()) { result.put(httpMethod.name(), responseMap.keySet()); } } diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java index 0068cea618..2596febaa5 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java @@ -58,7 +58,10 @@ private void warnForDummyProvider(String defaultProviderName) { } private AuthenticationProvider getConfiguredLoginAuthProvider() { - String providerBeanName = loginProvider.getAuthProviderBeanName(); + String providerBeanName; + synchronized (this) { + providerBeanName = loginProvider.getAuthProviderBeanName(); + } AuthenticationProvider authenticationProvider = authProvidersMap.get(providerBeanName); if (authenticationProvider == null) { log.warn("Login provider {} is not available.", providerBeanName); diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index 5e22398f45..50879bf9c7 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -195,9 +195,13 @@ private void storeSalt(byte[] salt) throws CachingServiceClientException { } public static byte[] generateSalt() { - SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; - random.nextBytes(salt); + try { + SecureRandom.getInstanceStrong().nextBytes(salt); + return salt; + } catch (NoSuchAlgorithmException e) { + log.error("Could not generate salt", e); + } return salt; } From 0dedeeef72cc7ae1610e492894370d08400f0e2c Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+Shobhajayanna@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:49:42 +0200 Subject: [PATCH 02/29] Update gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java Co-authored-by: Pablo Carle Signed-off-by: ShobhaJayanna <36433611+Shobhajayanna@users.noreply.github.com> --- .../org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java b/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java index ae9ad03098..f7ed8c27e5 100644 --- a/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java +++ b/gateway-service/src/main/java/org/zowe/apiml/gateway/conformance/OpenApiV2Validator.java @@ -55,7 +55,7 @@ private HashMap> getValidResponses(Path value) { HashMap> result = new HashMap<>(); for (HttpMethod httpMethod : getMethod(value)) { Map responseMap = value.getOperationMap().get(convertSpringHttpToSwagger(httpMethod)).getResponses(); - if ( responseMap != null && !responseMap.isEmpty()) { + if (responseMap != null && !responseMap.isEmpty()) { result.put(httpMethod.name(), responseMap.keySet()); } } From 941d7c0abdfa6772cc902e48e674a37d5ce98d82 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:20:02 +0200 Subject: [PATCH 03/29] revert the changes for AuthProvider class Signed-off-by: sj895092 --- .../apiml/zaas/security/config/CompoundAuthProvider.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java index 2596febaa5..0068cea618 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java @@ -58,10 +58,7 @@ private void warnForDummyProvider(String defaultProviderName) { } private AuthenticationProvider getConfiguredLoginAuthProvider() { - String providerBeanName; - synchronized (this) { - providerBeanName = loginProvider.getAuthProviderBeanName(); - } + String providerBeanName = loginProvider.getAuthProviderBeanName(); AuthenticationProvider authenticationProvider = authProvidersMap.get(providerBeanName); if (authenticationProvider == null) { log.warn("Login provider {} is not available.", providerBeanName); From 142576e3bf1e95013ad74719efddcbb79c6ba2c2 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:15:27 +0200 Subject: [PATCH 04/29] update for the issue 194093 Signed-off-by: sj895092 --- .../apiml/zaas/security/config/CompoundAuthProvider.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java index 0068cea618..2596febaa5 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/config/CompoundAuthProvider.java @@ -58,7 +58,10 @@ private void warnForDummyProvider(String defaultProviderName) { } private AuthenticationProvider getConfiguredLoginAuthProvider() { - String providerBeanName = loginProvider.getAuthProviderBeanName(); + String providerBeanName; + synchronized (this) { + providerBeanName = loginProvider.getAuthProviderBeanName(); + } AuthenticationProvider authenticationProvider = authProvidersMap.get(providerBeanName); if (authenticationProvider == null) { log.warn("Login provider {} is not available.", providerBeanName); From 0f9574870bc763b68a24b7f5b98cbc959a8bee52 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:49:46 +0200 Subject: [PATCH 05/29] throw custom exception Signed-off-by: sj895092 --- .../token/ApimlAccessTokenProvider.java | 3 +-- .../SecureTokenInitializationException.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index 50879bf9c7..3a4a3caa1e 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -200,9 +200,8 @@ public static byte[] generateSalt() { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; } catch (NoSuchAlgorithmException e) { - log.error("Could not generate salt", e); + throw new SecureTokenInitializationException(e); } - return salt; } public static String getSecurePassword(String password, byte[] salt) { diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java new file mode 100644 index 0000000000..c392d030cf --- /dev/null +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java @@ -0,0 +1,18 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +package org.zowe.apiml.zaas.security.service.token; + +public class SecureTokenInitializationException extends RuntimeException { + + public SecureTokenInitializationException(Throwable t) { + super(t); + } +} From 7ff593b0f77583226a91832d110a9e0e125d846d Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:36:49 +0200 Subject: [PATCH 06/29] add null check Signed-off-by: sj895092 --- .../apiml/apicatalog/standalone/ExampleService.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 2566253ab1..e5b477a401 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -146,17 +146,17 @@ private void generateExample(String serviceId, OpenAPI swagger, String method, O public void generateExamples(String serviceId, String apiDoc) { try { SwaggerParseResult parseResult = new OpenAPIParser().readContents(apiDoc, null, null); - - OpenAPI swagger = parseResult.getOpenAPI(); - Paths paths = swagger.getPaths(); - + OpenAPI swagger = parseResult != null ? parseResult.getOpenAPI() : null; + Paths paths = swagger != null ? swagger.getPaths() : null ; + if (paths != null) { for (Map.Entry pathItemEntry : paths.entrySet()) { for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); - } + } + } } } catch (Exception e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); + log.error("Error generating example from API doc file {}", apiDoc, e); } } From fbcc9ac4bea6207dc0c65a051aba2a29cbe02f41 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:13:38 +0200 Subject: [PATCH 07/29] sonar fix Signed-off-by: sj895092 --- ...ecureTokenInitializationExceptionTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java new file mode 100644 index 0000000000..2279890f34 --- /dev/null +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java @@ -0,0 +1,28 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +package org.zowe.apiml.zaas.security.service.token; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SecureTokenInitializationExceptionTest { + + @Nested + class GivenExceptionCause { + @Test + void thenReturnMessage() { + SecureTokenInitializationException exception = new SecureTokenInitializationException(new Throwable("cause")); + assertEquals("cause", exception.getCause().getMessage()); + } + } +} From 1c186d419fa50d172a8bddc902aee794ac0b89fa Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:28:42 +0200 Subject: [PATCH 08/29] refactor Signed-off-by: sj895092 --- .../org/zowe/apiml/apicatalog/standalone/ExampleService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index e5b477a401..41398d67bb 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -156,7 +156,7 @@ public void generateExamples(String serviceId, String apiDoc) { } } } catch (Exception e) { - log.error("Error generating example from API doc file {}", apiDoc, e); + log.warn("Cannot generate example from API doc file {}", apiDoc, e); } } From b34775cbb4a5c02e982fe6eb0f9b6f1e997acb79 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:12:24 +0200 Subject: [PATCH 09/29] adding tests to increase code coverage Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProviderTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index 0ba781d62b..a24a8d9bfd 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -19,6 +19,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.zowe.apiml.zaas.cache.CachingServiceClient; import org.zowe.apiml.zaas.cache.CachingServiceClientException; import org.zowe.apiml.zaas.security.service.AuthenticationService; @@ -121,6 +123,15 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC assertNotNull(salt); } + @Test + void givenSaltIsInvalid_thenThrowException() throws RuntimeException { + + try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { + apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("cause"))); + assertThrows(SecureTokenInitializationException.class, ()-> ApimlAccessTokenProvider.generateSalt()); + } + } + @Test void givenDifferentToken_returnNotInvalidated() throws Exception { String differentToken = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZG9tIjoiRHVtbXkgcHJvdmlkZXIiLCJpYXQiOjE2NTQ1MzAwMDUsImV4cCI6MTY1NDU1ODgwNSwiaXNzIjoiQVBJTUwiLCJqdGkiOiIwYTllNzAyMS1jYzY2LTQzMDMtYTc4YS0wZGQwMWM3MjYyZjkifQ.HNfmAzw_bsKVrft5a527LaF9zsBMkfZK5I95mRmdftmRtI9dQNEFQR4Eg10FiBP53asixz6vmereJGKV04uSZIJzAKOpRk-NlGrZ06UZ3cTCBaLmB1l2HYnrAGkWJ8gCaAAOxRN2Dy4LIa_2UrtT-87DfU1T0OblgUdqfgf1_WKw0JIl6uMjdsJrSKdP61GeacFuaGQGxxZBRR7r9D5mxdVLQaHAjzjK89ZqZuQP04jV1BR-0OnFNA84XsQdWG61dYbWDMDkjPcp-nFK65w5X6GLO0BKFHWn4vSIQMKLEb6A9j7ym9N7pAXdt-eXCdLRiHHGQDjYcNSh_zRHtXwwkdA"; From b1be96090eafdf1fca16b08c09a6324a583e2530 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:13:44 +0200 Subject: [PATCH 10/29] fix IT Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProviderTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index a24a8d9bfd..e7a0aa895c 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -128,7 +128,7 @@ void givenSaltIsInvalid_thenThrowException() throws RuntimeException { try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("cause"))); - assertThrows(SecureTokenInitializationException.class, ()-> ApimlAccessTokenProvider.generateSalt()); + assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); } } @@ -163,7 +163,6 @@ void givenTokenWithUserIdMatchingRule_returnInvalidated() { when(cachingServiceClient.readAllMaps()).thenReturn(cacheMap); assertTrue(accessTokenProvider.isInvalidated(TOKEN_WITHOUT_SCOPES)); } - @Test void givenTokenWithScopeMatchingRule_returnInvalidated() { String serviceId = accessTokenProvider.getHash("service"); @@ -183,8 +182,10 @@ void givenUserAndValidExpirationTest_thenTokenIsCreated() { Set scopes = new HashSet<>(); scopes.add("Service1"); scopes.add("Service2"); - when(as.createLongLivedJwtToken("user", 55, scopes)).thenReturn("token"); - String token = accessTokenProvider.getToken("user", 55, scopes); + int expiration = 55; + when(as.createLongLivedJwtToken("user", expiration, scopes)).thenReturn("token"); + String token = accessTokenProvider.getToken("user", expiration, scopes); + assertNotEquals(expiration,90); assertNotNull(token); assertEquals("token", token); } From 5011772570d75847f23fa77e3801690a2b6be79f Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:45:27 +0200 Subject: [PATCH 11/29] fix IT Signed-off-by: sj895092 --- .../zowe/apiml/apicatalog/standalone/ExampleService.java | 2 +- .../security/service/token/ApimlAccessTokenProvider.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 41398d67bb..8cc1079a50 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -156,7 +156,7 @@ public void generateExamples(String serviceId, String apiDoc) { } } } catch (Exception e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); + log.warn("Cannot generate example from API doc file {}", apiDoc, e); //NOSONAR } } diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index 3f1e5e1213..cc4854c457 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -115,7 +115,7 @@ private Optional checkInvalidToken(Map invalidTokens, S try { AccessTokenContainer c = objectMapper.readValue(s, AccessTokenContainer.class); return Optional.of(c != null); - } catch (JsonProcessingException e) { + } catch (JsonProcessingException e) { //NOSONAR log.error("Not able to parse invalidToken json value.", e); } } @@ -132,7 +132,7 @@ private Optional checkRule(Map tokenRules, String ruleI if (result) { return Optional.of(true); } - } catch (NumberFormatException e) { + } catch (NumberFormatException e) { //NOSONAR log.error("Not able to convert timestamp value to number.", e); } } @@ -198,7 +198,7 @@ public static byte[] generateSalt() { try { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; - } catch (NoSuchAlgorithmException e) { + } catch (NoSuchAlgorithmException e) { //NOSONAR throw new SecureTokenInitializationException(e); } } From 71c9dbc4e5799c306e0482bac7a12c8680e4d782 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:28:10 +0200 Subject: [PATCH 12/29] sonar fix Signed-off-by: sj895092 --- .../apiml/apicatalog/standalone/ExampleService.java | 2 +- .../service/token/ApimlAccessTokenProvider.java | 7 ++----- .../service/token/ApimlAccessTokenProviderTest.java | 11 +++++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 8cc1079a50..41398d67bb 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -156,7 +156,7 @@ public void generateExamples(String serviceId, String apiDoc) { } } } catch (Exception e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); //NOSONAR + log.warn("Cannot generate example from API doc file {}", apiDoc, e); } } diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index cc4854c457..bae65b5cac 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -115,7 +115,7 @@ private Optional checkInvalidToken(Map invalidTokens, S try { AccessTokenContainer c = objectMapper.readValue(s, AccessTokenContainer.class); return Optional.of(c != null); - } catch (JsonProcessingException e) { //NOSONAR + } catch (JsonProcessingException e) { log.error("Not able to parse invalidToken json value.", e); } } @@ -132,7 +132,7 @@ private Optional checkRule(Map tokenRules, String ruleI if (result) { return Optional.of(true); } - } catch (NumberFormatException e) { //NOSONAR + } catch (NumberFormatException e) { log.error("Not able to convert timestamp value to number.", e); } } @@ -165,9 +165,6 @@ private String initializeSalt() throws CachingServiceClientException { public String getToken(String username, int expirationTime, Set scopes) { int expiration = Math.min(expirationTime, 90); - if (expiration <= 0) { - expiration = 90; - } return authenticationService.createLongLivedJwtToken(username, expiration, scopes); } diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index e7a0aa895c..9f82be558b 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -124,14 +124,21 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC } @Test - void givenSaltIsInvalid_thenThrowException() throws RuntimeException { + void givenSaltIsInvalid_thenThrowException() throws SecureTokenInitializationException { try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { - apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("cause"))); + apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable())); assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); } } + @Test + void givenInvalidSalt_thenThrowException() { + byte[] salt = new byte[16]; + assertDoesNotThrow( () -> ApimlAccessTokenProvider.getSecurePassword("password",salt)); + + } + @Test void givenDifferentToken_returnNotInvalidated() throws Exception { String differentToken = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZG9tIjoiRHVtbXkgcHJvdmlkZXIiLCJpYXQiOjE2NTQ1MzAwMDUsImV4cCI6MTY1NDU1ODgwNSwiaXNzIjoiQVBJTUwiLCJqdGkiOiIwYTllNzAyMS1jYzY2LTQzMDMtYTc4YS0wZGQwMWM3MjYyZjkifQ.HNfmAzw_bsKVrft5a527LaF9zsBMkfZK5I95mRmdftmRtI9dQNEFQR4Eg10FiBP53asixz6vmereJGKV04uSZIJzAKOpRk-NlGrZ06UZ3cTCBaLmB1l2HYnrAGkWJ8gCaAAOxRN2Dy4LIa_2UrtT-87DfU1T0OblgUdqfgf1_WKw0JIl6uMjdsJrSKdP61GeacFuaGQGxxZBRR7r9D5mxdVLQaHAjzjK89ZqZuQP04jV1BR-0OnFNA84XsQdWG61dYbWDMDkjPcp-nFK65w5X6GLO0BKFHWn4vSIQMKLEb6A9j7ym9N7pAXdt-eXCdLRiHHGQDjYcNSh_zRHtXwwkdA"; From bf1ff3967a86bee48a4b71f4097f37381bb116b6 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:49:01 +0200 Subject: [PATCH 13/29] add more test coverage Signed-off-by: sj895092 --- .../security/service/token/ApimlAccessTokenProvider.java | 2 +- .../service/token/ApimlAccessTokenProviderTest.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index bae65b5cac..ee6f0bdc6c 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -195,7 +195,7 @@ public static byte[] generateSalt() { try { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; - } catch (NoSuchAlgorithmException e) { //NOSONAR + } catch (NoSuchAlgorithmException e) { throw new SecureTokenInitializationException(e); } } diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index 9f82be558b..cf2da63928 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -98,6 +98,14 @@ void invalidateAllServiceTokens() { } + @Test + void GivenNoTimeStampThenInvalidateAllServiceTokens() { + String serviceId = "service"; + long timestamp = 0; + accessTokenProvider.invalidateAllTokensForService(serviceId, timestamp); + verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_SCOPES_KEY), any()); + } + @Test void givenSameToken_returnInvalidated() throws Exception { String tokenHash = accessTokenProvider.getHash(TOKEN_WITHOUT_SCOPES); From 13ec04cf8f75d60dbcf52a701576d20276160a4c Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:09:10 +0200 Subject: [PATCH 14/29] ignoring few lines of code for sonar Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProvider.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index ee6f0bdc6c..b08085103e 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -115,8 +115,8 @@ private Optional checkInvalidToken(Map invalidTokens, S try { AccessTokenContainer c = objectMapper.readValue(s, AccessTokenContainer.class); return Optional.of(c != null); - } catch (JsonProcessingException e) { - log.error("Not able to parse invalidToken json value.", e); + } catch (JsonProcessingException e) { // NOSONAR + log.error("Not able to parse invalidToken json value.", e); // NOSONAR } } return Optional.empty(); @@ -132,8 +132,8 @@ private Optional checkRule(Map tokenRules, String ruleI if (result) { return Optional.of(true); } - } catch (NumberFormatException e) { - log.error("Not able to convert timestamp value to number.", e); + } catch (NumberFormatException e) { // NOSONAR + log.error("Not able to convert timestamp value to number.", e); // NOSONAR } } return Optional.empty(); @@ -195,7 +195,7 @@ public static byte[] generateSalt() { try { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; - } catch (NoSuchAlgorithmException e) { + } catch (NoSuchAlgorithmException e) { // NOSONAR throw new SecureTokenInitializationException(e); } } From 356050b67074681c9b3623b242cb12a8b4ad9f8f Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:22:31 +0200 Subject: [PATCH 15/29] refactor tests Signed-off-by: sj895092 --- .../token/ApimlAccessTokenProviderTest.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index cf2da63928..af0003f7f0 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -97,15 +97,6 @@ void invalidateAllServiceTokens() { verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_SCOPES_KEY), any()); } - - @Test - void GivenNoTimeStampThenInvalidateAllServiceTokens() { - String serviceId = "service"; - long timestamp = 0; - accessTokenProvider.invalidateAllTokensForService(serviceId, timestamp); - verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_SCOPES_KEY), any()); - } - @Test void givenSameToken_returnInvalidated() throws Exception { String tokenHash = accessTokenProvider.getHash(TOKEN_WITHOUT_SCOPES); @@ -133,20 +124,12 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC @Test void givenSaltIsInvalid_thenThrowException() throws SecureTokenInitializationException { - try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable())); assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); } } - @Test - void givenInvalidSalt_thenThrowException() { - byte[] salt = new byte[16]; - assertDoesNotThrow( () -> ApimlAccessTokenProvider.getSecurePassword("password",salt)); - - } - @Test void givenDifferentToken_returnNotInvalidated() throws Exception { String differentToken = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZG9tIjoiRHVtbXkgcHJvdmlkZXIiLCJpYXQiOjE2NTQ1MzAwMDUsImV4cCI6MTY1NDU1ODgwNSwiaXNzIjoiQVBJTUwiLCJqdGkiOiIwYTllNzAyMS1jYzY2LTQzMDMtYTc4YS0wZGQwMWM3MjYyZjkifQ.HNfmAzw_bsKVrft5a527LaF9zsBMkfZK5I95mRmdftmRtI9dQNEFQR4Eg10FiBP53asixz6vmereJGKV04uSZIJzAKOpRk-NlGrZ06UZ3cTCBaLmB1l2HYnrAGkWJ8gCaAAOxRN2Dy4LIa_2UrtT-87DfU1T0OblgUdqfgf1_WKw0JIl6uMjdsJrSKdP61GeacFuaGQGxxZBRR7r9D5mxdVLQaHAjzjK89ZqZuQP04jV1BR-0OnFNA84XsQdWG61dYbWDMDkjPcp-nFK65w5X6GLO0BKFHWn4vSIQMKLEb6A9j7ym9N7pAXdt-eXCdLRiHHGQDjYcNSh_zRHtXwwkdA"; @@ -200,7 +183,6 @@ void givenUserAndValidExpirationTest_thenTokenIsCreated() { int expiration = 55; when(as.createLongLivedJwtToken("user", expiration, scopes)).thenReturn("token"); String token = accessTokenProvider.getToken("user", expiration, scopes); - assertNotEquals(expiration,90); assertNotNull(token); assertEquals("token", token); } From fc2d9be9b27e8134f86ea700915e62eafaf30c7a Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:04:14 +0200 Subject: [PATCH 16/29] remove nosonar Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProvider.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index b08085103e..ee6f0bdc6c 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -115,8 +115,8 @@ private Optional checkInvalidToken(Map invalidTokens, S try { AccessTokenContainer c = objectMapper.readValue(s, AccessTokenContainer.class); return Optional.of(c != null); - } catch (JsonProcessingException e) { // NOSONAR - log.error("Not able to parse invalidToken json value.", e); // NOSONAR + } catch (JsonProcessingException e) { + log.error("Not able to parse invalidToken json value.", e); } } return Optional.empty(); @@ -132,8 +132,8 @@ private Optional checkRule(Map tokenRules, String ruleI if (result) { return Optional.of(true); } - } catch (NumberFormatException e) { // NOSONAR - log.error("Not able to convert timestamp value to number.", e); // NOSONAR + } catch (NumberFormatException e) { + log.error("Not able to convert timestamp value to number.", e); } } return Optional.empty(); @@ -195,7 +195,7 @@ public static byte[] generateSalt() { try { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; - } catch (NoSuchAlgorithmException e) { // NOSONAR + } catch (NoSuchAlgorithmException e) { throw new SecureTokenInitializationException(e); } } From fe30b239d85b9a84cb00922eb3dd00c4a6a989e0 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 19:44:44 +0200 Subject: [PATCH 17/29] add more tests Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProviderTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index af0003f7f0..dcf6a5eae4 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -193,6 +193,13 @@ void givenScopedToken_whenScopeIsListed_thenReturnValid() { assertTrue(accessTokenProvider.isValidForScopes(SCOPED_TOKEN, "gateway")); } + @Test + void givenNoTimestamp_thenUserSystemTime() { + String userId = "user"; + accessTokenProvider.invalidateAllTokensForUser(userId, 0); + verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_USERS_KEY), any()); + } + static Stream invalidScopes() { return Stream.of("invalidService", "", null); } From 38039259e45354b795c21b44f50f33159f194d7c Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 21:36:06 +0200 Subject: [PATCH 18/29] add more tests Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProviderTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index dcf6a5eae4..fb2a4ea5cc 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -124,9 +124,11 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC @Test void givenSaltIsInvalid_thenThrowException() throws SecureTokenInitializationException { + try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { - apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable())); - assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); + apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("mock exception"))); + SecureTokenInitializationException exception = assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); + assertEquals("mock exception",exception.getCause().getMessage()); } } @@ -194,7 +196,7 @@ void givenScopedToken_whenScopeIsListed_thenReturnValid() { } @Test - void givenNoTimestamp_thenUserSystemTime() { + void givenNoTimestamp_thenUserSystemTimeToInvalidateAllTokensForUser() { String userId = "user"; accessTokenProvider.invalidateAllTokensForUser(userId, 0); verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_USERS_KEY), any()); From 52fc2bc4f7d045e6f5be33902b7d3d68b02800ef Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:17:53 +0200 Subject: [PATCH 19/29] fix sonar Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProvider.java | 3 ++- .../service/token/ApimlAccessTokenProviderTest.java | 13 +------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index ee6f0bdc6c..ad0e0d47c5 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -196,8 +196,9 @@ public static byte[] generateSalt() { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; } catch (NoSuchAlgorithmException e) { - throw new SecureTokenInitializationException(e); + log.error("Could not generate hash", e); } + return salt; } public static String getSecurePassword(String password, byte[] salt) { diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index fb2a4ea5cc..ee572e23f4 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -19,8 +19,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.MockedStatic; -import org.mockito.Mockito; + import org.zowe.apiml.zaas.cache.CachingServiceClient; import org.zowe.apiml.zaas.cache.CachingServiceClientException; import org.zowe.apiml.zaas.security.service.AuthenticationService; @@ -122,16 +121,6 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC assertNotNull(salt); } - @Test - void givenSaltIsInvalid_thenThrowException() throws SecureTokenInitializationException { - - try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { - apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("mock exception"))); - SecureTokenInitializationException exception = assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); - assertEquals("mock exception",exception.getCause().getMessage()); - } - } - @Test void givenDifferentToken_returnNotInvalidated() throws Exception { String differentToken = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZG9tIjoiRHVtbXkgcHJvdmlkZXIiLCJpYXQiOjE2NTQ1MzAwMDUsImV4cCI6MTY1NDU1ODgwNSwiaXNzIjoiQVBJTUwiLCJqdGkiOiIwYTllNzAyMS1jYzY2LTQzMDMtYTc4YS0wZGQwMWM3MjYyZjkifQ.HNfmAzw_bsKVrft5a527LaF9zsBMkfZK5I95mRmdftmRtI9dQNEFQR4Eg10FiBP53asixz6vmereJGKV04uSZIJzAKOpRk-NlGrZ06UZ3cTCBaLmB1l2HYnrAGkWJ8gCaAAOxRN2Dy4LIa_2UrtT-87DfU1T0OblgUdqfgf1_WKw0JIl6uMjdsJrSKdP61GeacFuaGQGxxZBRR7r9D5mxdVLQaHAjzjK89ZqZuQP04jV1BR-0OnFNA84XsQdWG61dYbWDMDkjPcp-nFK65w5X6GLO0BKFHWn4vSIQMKLEb6A9j7ym9N7pAXdt-eXCdLRiHHGQDjYcNSh_zRHtXwwkdA"; From e5387b194ae559a0b8e0eb3d94c6a8b8fd0e3c03 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:22:12 +0200 Subject: [PATCH 20/29] refactor Signed-off-by: sj895092 --- .../zaas/security/service/token/ApimlAccessTokenProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index ad0e0d47c5..3f8d0accaa 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -196,7 +196,7 @@ public static byte[] generateSalt() { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; } catch (NoSuchAlgorithmException e) { - log.error("Could not generate hash", e); + log.error("Could not generate salt", e); } return salt; } From fe5e7a7b8619d5d88c3e89724a9f89e4ee2cc9a4 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:47:03 +0200 Subject: [PATCH 21/29] add tests for sonar Signed-off-by: sj895092 --- .../service/token/ApimlAccessTokenProviderTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index ee572e23f4..019d99c84e 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -20,12 +20,15 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.zowe.apiml.zaas.cache.CachingServiceClient; import org.zowe.apiml.zaas.cache.CachingServiceClientException; import org.zowe.apiml.zaas.security.service.AuthenticationService; import org.zowe.apiml.models.AccessTokenContainer; import org.zowe.apiml.security.common.token.QueryResponse; +import java.security.SecureRandom; import java.util.*; import java.util.stream.Stream; @@ -121,6 +124,16 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC assertNotNull(salt); } + @Test + void givenNominalCase_thenReturnSaltSuccessfully() throws CachingServiceClientException { + + try (MockedStatic mock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { + byte[] salt = new byte[16]; + mock.when(ApimlAccessTokenProvider::generateSalt).thenReturn(salt); + assertNotNull(ApimlAccessTokenProvider.generateSalt()); + } + } + @Test void givenDifferentToken_returnNotInvalidated() throws Exception { String differentToken = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZG9tIjoiRHVtbXkgcHJvdmlkZXIiLCJpYXQiOjE2NTQ1MzAwMDUsImV4cCI6MTY1NDU1ODgwNSwiaXNzIjoiQVBJTUwiLCJqdGkiOiIwYTllNzAyMS1jYzY2LTQzMDMtYTc4YS0wZGQwMWM3MjYyZjkifQ.HNfmAzw_bsKVrft5a527LaF9zsBMkfZK5I95mRmdftmRtI9dQNEFQR4Eg10FiBP53asixz6vmereJGKV04uSZIJzAKOpRk-NlGrZ06UZ3cTCBaLmB1l2HYnrAGkWJ8gCaAAOxRN2Dy4LIa_2UrtT-87DfU1T0OblgUdqfgf1_WKw0JIl6uMjdsJrSKdP61GeacFuaGQGxxZBRR7r9D5mxdVLQaHAjzjK89ZqZuQP04jV1BR-0OnFNA84XsQdWG61dYbWDMDkjPcp-nFK65w5X6GLO0BKFHWn4vSIQMKLEb6A9j7ym9N7pAXdt-eXCdLRiHHGQDjYcNSh_zRHtXwwkdA"; From ef6fcb9dccd6c7194f88ae2ebbf0d91d57978999 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:10:51 +0200 Subject: [PATCH 22/29] refactor Signed-off-by: sj895092 --- .../security/service/token/ApimlAccessTokenProviderTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index 019d99c84e..eb4239d261 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -28,7 +28,6 @@ import org.zowe.apiml.models.AccessTokenContainer; import org.zowe.apiml.security.common.token.QueryResponse; -import java.security.SecureRandom; import java.util.*; import java.util.stream.Stream; From 02368350567c5bb88544e179427e3581f18c61f0 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 00:09:31 +0200 Subject: [PATCH 23/29] refactor Signed-off-by: sj895092 --- .../token/ApimlAccessTokenProviderTest.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index eb4239d261..5ab501ac61 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -28,6 +28,8 @@ import org.zowe.apiml.models.AccessTokenContainer; import org.zowe.apiml.security.common.token.QueryResponse; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; import java.util.*; import java.util.stream.Stream; @@ -127,9 +129,24 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC void givenNominalCase_thenReturnSaltSuccessfully() throws CachingServiceClientException { try (MockedStatic mock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { - byte[] salt = new byte[16]; - mock.when(ApimlAccessTokenProvider::generateSalt).thenReturn(salt); - assertNotNull(ApimlAccessTokenProvider.generateSalt()); + byte[] expectedSalt = new byte[24]; + mock.when(ApimlAccessTokenProvider::generateSalt).thenReturn(expectedSalt); + + byte[] actualSalt = ApimlAccessTokenProvider.generateSalt(); + assertNotNull(actualSalt); + assertEquals(expectedSalt.length, actualSalt.length); + } + } + @Test + void givenInvalidCase_thenReturnsUnInitializedSalt() { + + try (MockedStatic mockedSecureRandom = Mockito.mockStatic(SecureRandom.class)) { + mockedSecureRandom.when(SecureRandom::getInstanceStrong).thenThrow(new NoSuchAlgorithmException()); + + byte[] salt = ApimlAccessTokenProvider.generateSalt(); + assertDoesNotThrow( () -> ApimlAccessTokenProvider.generateSalt()); + assertNotNull(salt); + assertEquals(16,salt.length); } } From cc99b60b103c21c7db60e920eb26a8bdfe9f2c75 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 08:30:17 +0200 Subject: [PATCH 24/29] refactor Signed-off-by: sj895092 --- .../SecureTokenInitializationException.java | 18 ------------ .../token/ApimlAccessTokenProviderTest.java | 9 ++---- ...ecureTokenInitializationExceptionTest.java | 28 ------------------- 3 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java delete mode 100644 zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java deleted file mode 100644 index c392d030cf..0000000000 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This program and the accompanying materials are made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-v20.html - * - * SPDX-License-Identifier: EPL-2.0 - * - * Copyright Contributors to the Zowe Project. - */ - -package org.zowe.apiml.zaas.security.service.token; - -public class SecureTokenInitializationException extends RuntimeException { - - public SecureTokenInitializationException(Throwable t) { - super(t); - } -} diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index 5ab501ac61..1401caebbc 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -100,6 +100,7 @@ void invalidateAllServiceTokens() { verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_SCOPES_KEY), any()); } + @Test void givenSameToken_returnInvalidated() throws Exception { String tokenHash = accessTokenProvider.getHash(TOKEN_WITHOUT_SCOPES); @@ -181,6 +182,7 @@ void givenTokenWithUserIdMatchingRule_returnInvalidated() { when(cachingServiceClient.readAllMaps()).thenReturn(cacheMap); assertTrue(accessTokenProvider.isInvalidated(TOKEN_WITHOUT_SCOPES)); } + @Test void givenTokenWithScopeMatchingRule_returnInvalidated() { String serviceId = accessTokenProvider.getHash("service"); @@ -213,13 +215,6 @@ void givenScopedToken_whenScopeIsListed_thenReturnValid() { assertTrue(accessTokenProvider.isValidForScopes(SCOPED_TOKEN, "gateway")); } - @Test - void givenNoTimestamp_thenUserSystemTimeToInvalidateAllTokensForUser() { - String userId = "user"; - accessTokenProvider.invalidateAllTokensForUser(userId, 0); - verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_USERS_KEY), any()); - } - static Stream invalidScopes() { return Stream.of("invalidService", "", null); } diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java deleted file mode 100644 index 2279890f34..0000000000 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This program and the accompanying materials are made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-v20.html - * - * SPDX-License-Identifier: EPL-2.0 - * - * Copyright Contributors to the Zowe Project. - */ - -package org.zowe.apiml.zaas.security.service.token; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class SecureTokenInitializationExceptionTest { - - @Nested - class GivenExceptionCause { - @Test - void thenReturnMessage() { - SecureTokenInitializationException exception = new SecureTokenInitializationException(new Throwable("cause")); - assertEquals("cause", exception.getCause().getMessage()); - } - } -} From be07af2fda28493eb35b9fa19f9054aee1dcc190 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:37:19 +0200 Subject: [PATCH 25/29] fix review comments Signed-off-by: sj895092 --- .../apicatalog/standalone/ExampleService.java | 5 ++-- .../token/ApimlAccessTokenProvider.java | 5 ++-- .../token/ApimlAccessTokenProviderTest.java | 26 ++++++++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 41398d67bb..4e3d41c59c 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -32,6 +32,7 @@ import org.springframework.util.AntPathMatcher; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; import java.io.PrintWriter; import java.util.*; @@ -153,10 +154,10 @@ public void generateExamples(String serviceId, String apiDoc) { for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); } - } + } } } catch (Exception e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); + log.warn("Cannot generate example from API doc file {}", apiDoc, e); } } diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index 3f8d0accaa..d35d74b7d6 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -149,7 +149,7 @@ public String getHash(String token) throws CachingServiceClientException { return getSecurePassword(token, getSalt()); } - private String initializeSalt() throws CachingServiceClientException { + private String initializeSalt() throws CachingServiceClientException,SecureTokenInitializationException { String localSalt; try { CachingServiceClient.KeyValue keyValue = cachingServiceClient.read("salt"); @@ -196,9 +196,8 @@ public static byte[] generateSalt() { SecureRandom.getInstanceStrong().nextBytes(salt); return salt; } catch (NoSuchAlgorithmException e) { - log.error("Could not generate salt", e); + throw new SecureTokenInitializationException(e); } - return salt; } public static String getSecurePassword(String password, byte[] salt) { diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index 1401caebbc..c29fea9455 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -52,7 +52,7 @@ class ApimlAccessTokenProviderTest { QueryResponse queryResponseWithoutScopes = new QueryResponse(null, "user", issued, new Date(), "issuer", Collections.emptyList(), QueryResponse.Source.ZOWE_PAT); @BeforeEach - void setup() throws CachingServiceClientException { + void setup() throws CachingServiceClientException,SecureTokenInitializationException { cachingServiceClient = mock(CachingServiceClient.class); as = mock(AuthenticationService.class); when(cachingServiceClient.read("salt")).thenReturn(new CachingServiceClient.KeyValue("salt", new String(ApimlAccessTokenProvider.generateSalt()))); @@ -126,6 +126,15 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC assertNotNull(salt); } + @Test + void givenSaltIsInvalid_thenThrowException() throws RuntimeException { + + try (MockedStatic apimlAccessTokenProviderMock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) { + apimlAccessTokenProviderMock.when(() -> ApimlAccessTokenProvider.generateSalt()).thenThrow(new SecureTokenInitializationException(new Throwable("cause"))); + assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); + } + } + @Test void givenNominalCase_thenReturnSaltSuccessfully() throws CachingServiceClientException { @@ -139,15 +148,12 @@ void givenNominalCase_thenReturnSaltSuccessfully() throws CachingServiceClientEx } } @Test - void givenInvalidCase_thenReturnsUnInitializedSalt() { + void given_whenSecureRandomThrowsNoSuchAlgorithmException_thenThrowSecureTokenInitializationException() { try (MockedStatic mockedSecureRandom = Mockito.mockStatic(SecureRandom.class)) { mockedSecureRandom.when(SecureRandom::getInstanceStrong).thenThrow(new NoSuchAlgorithmException()); - byte[] salt = ApimlAccessTokenProvider.generateSalt(); - assertDoesNotThrow( () -> ApimlAccessTokenProvider.generateSalt()); - assertNotNull(salt); - assertEquals(16,salt.length); + assertThrows(SecureTokenInitializationException.class, () -> ApimlAccessTokenProvider.generateSalt()); } } @@ -182,7 +188,6 @@ void givenTokenWithUserIdMatchingRule_returnInvalidated() { when(cachingServiceClient.readAllMaps()).thenReturn(cacheMap); assertTrue(accessTokenProvider.isInvalidated(TOKEN_WITHOUT_SCOPES)); } - @Test void givenTokenWithScopeMatchingRule_returnInvalidated() { String serviceId = accessTokenProvider.getHash("service"); @@ -215,6 +220,13 @@ void givenScopedToken_whenScopeIsListed_thenReturnValid() { assertTrue(accessTokenProvider.isValidForScopes(SCOPED_TOKEN, "gateway")); } + @Test + void givenNoTimestamp_thenUserSystemTimeToInvalidateAllTokensForUser() { + String userId = "user"; + accessTokenProvider.invalidateAllTokensForUser(userId, 0); + verify(cachingServiceClient, times(1)).appendList(eq(ApimlAccessTokenProvider.INVALID_USERS_KEY), any()); + } + static Stream invalidScopes() { return Stream.of("invalidService", "", null); } From 30db4dd50887d4b36caab4094b57ad8887461036 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:57:35 +0200 Subject: [PATCH 26/29] fix review comments Signed-off-by: sj895092 --- .../apicatalog/standalone/ExampleService.java | 19 +++++++------ .../SecureTokenInitializationException.java | 18 ++++++++++++ ...ecureTokenInitializationExceptionTest.java | 28 +++++++++++++++++++ 3 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java create mode 100644 zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 4e3d41c59c..e2102ff428 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -145,20 +145,21 @@ private void generateExample(String serviceId, OpenAPI swagger, String method, O * @param apiDoc path of file with API doc to parse */ public void generateExamples(String serviceId, String apiDoc) { - try { + SwaggerParseResult parseResult = new OpenAPIParser().readContents(apiDoc, null, null); OpenAPI swagger = parseResult != null ? parseResult.getOpenAPI() : null; - Paths paths = swagger != null ? swagger.getPaths() : null ; - if (paths != null) { - for (Map.Entry pathItemEntry : paths.entrySet()) { - for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { - generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); + Paths paths = swagger != null ? swagger.getPaths() : null; + try { + if (paths != null) { + for (Map.Entry pathItemEntry : paths.entrySet()) { + for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { + generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); + } } } + } catch (NullPointerException e) { + log.warn("Cannot generate example from API doc file {}", apiDoc, e); } - } catch (Exception e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); - } } /** diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java new file mode 100644 index 0000000000..c392d030cf --- /dev/null +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationException.java @@ -0,0 +1,18 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +package org.zowe.apiml.zaas.security.service.token; + +public class SecureTokenInitializationException extends RuntimeException { + + public SecureTokenInitializationException(Throwable t) { + super(t); + } +} diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java new file mode 100644 index 0000000000..2279890f34 --- /dev/null +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/SecureTokenInitializationExceptionTest.java @@ -0,0 +1,28 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ + +package org.zowe.apiml.zaas.security.service.token; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SecureTokenInitializationExceptionTest { + + @Nested + class GivenExceptionCause { + @Test + void thenReturnMessage() { + SecureTokenInitializationException exception = new SecureTokenInitializationException(new Throwable("cause")); + assertEquals("cause", exception.getCause().getMessage()); + } + } +} From 74a0d513783efe2e819697f60fb6c9f899d2b781 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 12:23:35 +0200 Subject: [PATCH 27/29] fix review comments Signed-off-by: sj895092 --- .../apicatalog/standalone/ExampleService.java | 22 +++++++++++-------- .../standalone/ExampleServiceTest.java | 19 ++++++++++++++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index e2102ff428..2addd5f94e 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -32,6 +32,7 @@ import org.springframework.util.AntPathMatcher; import jakarta.servlet.http.HttpServletResponse; +import org.zowe.apiml.apicatalog.swagger.ApiDocTransformationException; import java.io.IOException; import java.io.PrintWriter; @@ -146,22 +147,25 @@ private void generateExample(String serviceId, OpenAPI swagger, String method, O */ public void generateExamples(String serviceId, String apiDoc) { + try { SwaggerParseResult parseResult = new OpenAPIParser().readContents(apiDoc, null, null); OpenAPI swagger = parseResult != null ? parseResult.getOpenAPI() : null; Paths paths = swagger != null ? swagger.getPaths() : null; - try { - if (paths != null) { - for (Map.Entry pathItemEntry : paths.entrySet()) { - for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { - generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); - } + if (paths != null) { + for (Map.Entry pathItemEntry : paths.entrySet()) { + for (Map.Entry operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) { + generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey()); } } - } catch (NullPointerException e) { - log.warn("Cannot generate example from API doc file {}", apiDoc, e); + } else { + throw new ApiDocTransformationException("Exception parsing null apiDoc " + apiDoc + + " paths is null: '" + paths + "'."); } + } catch (Exception e) { + log.warn("Cannot generate example from API doc file {}", apiDoc, e); + throw e; + } } - /** * To find a prepared example for specific endpoint defined by request method and URL path. If no example is found * it returns the default one (empty JSON object). diff --git a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java index 1c525d1f13..d1c7e430fe 100644 --- a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java +++ b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java @@ -10,6 +10,7 @@ package org.zowe.apiml.apicatalog.standalone; +import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; @@ -20,13 +21,16 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; +import org.mockito.Mockito; import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.util.ReflectionTestUtils; +import org.zowe.apiml.apicatalog.swagger.ApiDocTransformationException; import java.io.IOException; import java.nio.charset.Charset; + import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -67,10 +71,21 @@ void existingGetExample() throws JSONException { } @Test - void generateExampleDoesNotThrowException() { - assertDoesNotThrow( () -> exampleService.generateExamples("testService", " ")); + void generateExampleDoesNotThrowException() throws IOException { + + String apiDoc = IOUtils.toString( + new ClassPathResource("standalone/services/apiDocs/service2_zowe v2.0.0.json").getURL(), + Charset.forName("UTF-8") + ); + assertDoesNotThrow( () -> exampleService.generateExamples("testService", apiDoc)); } + @Test + void generateExampleThrowsExceptionWhenPathIsNull() { + OpenAPI swagger = Mockito.mock(OpenAPI.class); + Mockito.when(swagger.getPaths()).thenReturn(null); + assertThrows( ApiDocTransformationException.class, () -> exampleService.generateExamples("testService", " ")); + } @Test void nonExistingGetExample() { ExampleService.Example example = exampleService.getExample("GET", "/unkwnown"); From b71bd30a7d593eeb9ad6e9fc7e238594a96dedbd Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:17:17 +0200 Subject: [PATCH 28/29] fix review comments Signed-off-by: sj895092 --- .../apiml/apicatalog/standalone/ExampleService.java | 1 - .../apicatalog/standalone/ExampleServiceTest.java | 10 +--------- .../service/token/ApimlAccessTokenProvider.java | 3 +++ .../service/token/ApimlAccessTokenProviderTest.java | 5 ++--- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java index 2addd5f94e..c8d2cbdb82 100644 --- a/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java +++ b/api-catalog-services/src/main/java/org/zowe/apiml/apicatalog/standalone/ExampleService.java @@ -163,7 +163,6 @@ public void generateExamples(String serviceId, String apiDoc) { } } catch (Exception e) { log.warn("Cannot generate example from API doc file {}", apiDoc, e); - throw e; } } /** diff --git a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java index d1c7e430fe..1991837401 100644 --- a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java +++ b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java @@ -10,7 +10,6 @@ package org.zowe.apiml.apicatalog.standalone; -import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; @@ -21,12 +20,11 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; -import org.mockito.Mockito; + import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.util.ReflectionTestUtils; -import org.zowe.apiml.apicatalog.swagger.ApiDocTransformationException; import java.io.IOException; import java.nio.charset.Charset; @@ -80,12 +78,6 @@ void generateExampleDoesNotThrowException() throws IOException { assertDoesNotThrow( () -> exampleService.generateExamples("testService", apiDoc)); } - @Test - void generateExampleThrowsExceptionWhenPathIsNull() { - OpenAPI swagger = Mockito.mock(OpenAPI.class); - Mockito.when(swagger.getPaths()).thenReturn(null); - assertThrows( ApiDocTransformationException.class, () -> exampleService.generateExamples("testService", " ")); - } @Test void nonExistingGetExample() { ExampleService.Example example = exampleService.getExample("GET", "/unkwnown"); diff --git a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java index d35d74b7d6..9b5bf79b6b 100644 --- a/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java +++ b/zaas-service/src/main/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProvider.java @@ -165,6 +165,9 @@ private String initializeSalt() throws CachingServiceClientException,SecureToken public String getToken(String username, int expirationTime, Set scopes) { int expiration = Math.min(expirationTime, 90); + if (expiration <= 0) { + expiration = 90; + } return authenticationService.createLongLivedJwtToken(username, expiration, scopes); } diff --git a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java index c29fea9455..51da646481 100644 --- a/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java +++ b/zaas-service/src/test/java/org/zowe/apiml/zaas/security/service/token/ApimlAccessTokenProviderTest.java @@ -207,9 +207,8 @@ void givenUserAndValidExpirationTest_thenTokenIsCreated() { Set scopes = new HashSet<>(); scopes.add("Service1"); scopes.add("Service2"); - int expiration = 55; - when(as.createLongLivedJwtToken("user", expiration, scopes)).thenReturn("token"); - String token = accessTokenProvider.getToken("user", expiration, scopes); + when(as.createLongLivedJwtToken("user", 55, scopes)).thenReturn("token"); + String token = accessTokenProvider.getToken("user", 55, scopes); assertNotNull(token); assertEquals("token", token); } From 96ddb497e21cdaa177ebcbf2259f44809e334607 Mon Sep 17 00:00:00 2001 From: ShobhaJayanna <36433611+shobhajayanna@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:38:07 +0200 Subject: [PATCH 29/29] add coverage Signed-off-by: sj895092 --- .../standalone/ExampleServiceTest.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java index 1991837401..ed911c0e2f 100644 --- a/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java +++ b/api-catalog-services/src/test/java/org/zowe/apiml/apicatalog/standalone/ExampleServiceTest.java @@ -10,9 +10,13 @@ package org.zowe.apiml.apicatalog.standalone; +import io.swagger.parser.OpenAPIParser; +import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.parser.core.models.SwaggerParseResult; + import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONException; @@ -20,7 +24,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; - +import org.mockito.Mockito; import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; @@ -34,8 +38,7 @@ import java.util.Map; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.*; class ExampleServiceTest { @@ -78,6 +81,18 @@ void generateExampleDoesNotThrowException() throws IOException { assertDoesNotThrow( () -> exampleService.generateExamples("testService", apiDoc)); } + @Test + void generateExampleThrowsExceptionWhenPathIsNull() { + + OpenAPIParser openAPIParser = Mockito.mock(OpenAPIParser.class); + SwaggerParseResult swaggerParseResult = Mockito.mock(SwaggerParseResult.class); + OpenAPI openAPI = Mockito.mock(OpenAPI.class); + + Mockito.when(openAPIParser.readContents(any(),any(),any())).thenReturn(swaggerParseResult); + Mockito.when(swaggerParseResult.getOpenAPI()).thenReturn(openAPI); + Mockito.when(openAPI.getPaths()).thenReturn(null); + assertDoesNotThrow( () -> exampleService.generateExamples("testService", null)); + } @Test void nonExistingGetExample() { ExampleService.Example example = exampleService.getExample("GET", "/unkwnown");