Skip to content

Commit

Permalink
fix: fix coverity issues for v3 release (#3774)
Browse files Browse the repository at this point in the history
* fix coverity issues in v3

Signed-off-by: sj895092 <[email protected]>
  • Loading branch information
Shobhajayanna authored Sep 19, 2024
1 parent fb46c52 commit 982ca45
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
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;
import java.util.*;
Expand Down Expand Up @@ -144,22 +146,25 @@ 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.getOpenAPI();
Paths paths = swagger.getPaths();

for (Map.Entry<String, PathItem> pathItemEntry : paths.entrySet()) {
for (Map.Entry<PathItem.HttpMethod, Operation> operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) {
generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey());
OpenAPI swagger = parseResult != null ? parseResult.getOpenAPI() : null;
Paths paths = swagger != null ? swagger.getPaths() : null;
if (paths != null) {
for (Map.Entry<String, PathItem> pathItemEntry : paths.entrySet()) {
for (Map.Entry<PathItem.HttpMethod, Operation> operationEntry : pathItemEntry.getValue().readOperationsMap().entrySet()) {
generateExample(serviceId, swagger, operationEntry.getKey().name(), operationEntry.getValue(), pathItemEntry.getKey());
}
}
} 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);
}
}

/**
* 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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,35 @@

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;
import org.junit.jupiter.api.BeforeAll;
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 java.io.IOException;
import java.nio.charset.Charset;

import java.util.LinkedHashMap;
import java.util.List;
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 {

Expand Down Expand Up @@ -67,10 +72,27 @@ 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() {

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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private HashMap<String, Set<String>> getValidResponses(Path value) {
HashMap<String, Set<String>> result = new HashMap<>();
for (HttpMethod httpMethod : getMethod(value)) {
Map<String, Response> responseMap = value.getOperationMap().get(convertSpringHttpToSwagger(httpMethod)).getResponses();
if ( !responseMap.isEmpty()) {
if (responseMap != null && !responseMap.isEmpty()) {
result.put(httpMethod.name(), responseMap.keySet());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -194,10 +194,13 @@ private void storeSalt(byte[] salt) throws CachingServiceClientException {
}

public static byte[] generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return salt;
try {
SecureRandom.getInstanceStrong().nextBytes(salt);
return salt;
} catch (NoSuchAlgorithmException e) {
throw new SecureTokenInitializationException(e);
}
}

public static String getSecurePassword(String password, byte[] salt) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@
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;
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;

Expand All @@ -47,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())));
Expand Down Expand Up @@ -121,6 +126,37 @@ void givenSaltNotAlreadyInCache_thenGenerateAndStoreNew() throws CachingServiceC
assertNotNull(salt);
}

@Test
void givenSaltIsInvalid_thenThrowException() throws RuntimeException {

try (MockedStatic<ApimlAccessTokenProvider> 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 {

try (MockedStatic<ApimlAccessTokenProvider> mock = Mockito.mockStatic(ApimlAccessTokenProvider.class)) {
byte[] expectedSalt = new byte[24];
mock.when(ApimlAccessTokenProvider::generateSalt).thenReturn(expectedSalt);

byte[] actualSalt = ApimlAccessTokenProvider.generateSalt();
assertNotNull(actualSalt);
assertEquals(expectedSalt.length, actualSalt.length);
}
}
@Test
void given_whenSecureRandomThrowsNoSuchAlgorithmException_thenThrowSecureTokenInitializationException() {

try (MockedStatic<SecureRandom> mockedSecureRandom = Mockito.mockStatic(SecureRandom.class)) {
mockedSecureRandom.when(SecureRandom::getInstanceStrong).thenThrow(new NoSuchAlgorithmException());

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";
Expand Down Expand Up @@ -152,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");
Expand Down Expand Up @@ -184,6 +219,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<String> invalidScopes() {
return Stream.of("invalidService", "", null);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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());
}
}
}

0 comments on commit 982ca45

Please sign in to comment.