Skip to content

Commit

Permalink
[EDGORDERS-83-IT]. Add tls integration test, add test scope BC deps, … (
Browse files Browse the repository at this point in the history
#102)

* [EDGORDERS-83-IT]. Add tls integration test, add test scope BC deps, keystore and trust store
  • Loading branch information
BKadirkhodjaev authored May 22, 2024
1 parent 99e7575 commit bc84d49
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<bc-fips.version>1.0.2.5</bc-fips.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -89,6 +90,13 @@
<version>5.11.0</version>
<scope>test</scope>
</dependency>
<!-- Library provides the basic cryptographic functionality complying with FIPS for testing -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>${bc-fips.version}</version>
<scope>test</scope>
</dependency>

<!-- provided dependencies needed for MockOkapi and TestUtils -->
<dependency>
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/folio/edge/core/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,33 @@ private Constants() {
defaultMap.put(SYS_HTTP_SERVER_SSL_ENABLED,
Boolean.parseBoolean(System.getProperty(SYS_HTTP_SERVER_SSL_ENABLED,
Boolean.toString(DEFAULT_SSL_ENABLED))));
defaultMap.put(SYS_HTTP_SERVER_KEYSTORE_TYPE,
System.getProperty(SYS_HTTP_SERVER_KEYSTORE_TYPE));
defaultMap.put(SYS_HTTP_SERVER_KEYSTORE_PROVIDER,
System.getProperty(SYS_HTTP_SERVER_KEYSTORE_PROVIDER));
defaultMap.put(SYS_HTTP_SERVER_KEYSTORE_PATH,
System.getProperty(SYS_HTTP_SERVER_KEYSTORE_PATH));
defaultMap.put(SYS_HTTP_SERVER_KEYSTORE_PASSWORD,
System.getProperty(SYS_HTTP_SERVER_KEYSTORE_PASSWORD));
defaultMap.put(SYS_HTTP_SERVER_KEY_ALIAS,
System.getProperty(SYS_HTTP_SERVER_KEY_ALIAS));
defaultMap.put(SYS_HTTP_SERVER_KEY_ALIAS_PASSWORD,
System.getProperty(SYS_HTTP_SERVER_KEY_ALIAS_PASSWORD));
defaultMap.put(SYS_WEB_CLIENT_SSL_ENABLED,
Boolean.parseBoolean(System.getProperty(SYS_WEB_CLIENT_SSL_ENABLED,
Boolean.toString(DEFAULT_SSL_ENABLED))));
defaultMap.put(SYS_WEB_CLIENT_TRUSTSTORE_TYPE,
System.getProperty(SYS_WEB_CLIENT_TRUSTSTORE_TYPE));
defaultMap.put(SYS_WEB_CLIENT_TRUSTSTORE_PROVIDER,
System.getProperty(SYS_WEB_CLIENT_TRUSTSTORE_PROVIDER));
defaultMap.put(SYS_WEB_CLIENT_TRUSTSTORE_PATH,
System.getProperty(SYS_WEB_CLIENT_TRUSTSTORE_PATH));
defaultMap.put(SYS_WEB_CLIENT_TRUSTSTORE_PASSWORD,
System.getProperty(SYS_WEB_CLIENT_TRUSTSTORE_PASSWORD));
defaultMap.put(SYS_WEB_CLIENT_KEY_ALIAS,
System.getProperty(SYS_WEB_CLIENT_KEY_ALIAS));
defaultMap.put(SYS_WEB_CLIENT_KEY_ALIAS_PASSWORD,
System.getProperty(SYS_WEB_CLIENT_KEY_ALIAS_PASSWORD));
defaultMap.put(SYS_SECURE_STORE_PROP_FILE,
System.getProperty(SYS_SECURE_STORE_PROP_FILE));
defaultMap.put(SYS_OKAPI_URL,
Expand Down
147 changes: 147 additions & 0 deletions src/test/java/org/folio/edge/core/EdgeVerticleTlsIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package org.folio.edge.core;

import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.core.AsyncResult;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.folio.edge.core.utils.OkapiClient;
import org.folio.edge.core.utils.OkapiClientFactory;
import org.folio.edge.core.utils.OkapiClientFactoryInitializer;
import org.folio.edge.core.utils.SslConfigurationUtil;
import org.folio.edge.core.utils.test.TestUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.security.Security;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

@RunWith(VertxUnitRunner.class)
public class EdgeVerticleTlsIntegrationTest {

private static final Logger logger = LogManager.getLogger(EdgeVerticleTlsIntegrationTest.class);
private static Vertx vertx;

private static final String KEYSTORE_TYPE = "BCFKS";
private static final String KEYSTORE_PATH = "test.keystore 1.bcfks";
private static final String TRUST_STORE_PATH = "test.truststore 1.bcfks";
private static final String KEYSTORE_PASSWORD = "SecretPassword";
private static final String RESPONSE_MESSAGE = "<OK>";
private static final String OKAPI_URL = "http://localhost:" + TestUtils.getPort();
private static final String TENANT = "diku";

@Before
public void setUpOnce() {
Security.addProvider(new BouncyCastleFipsProvider());
vertx = Vertx.vertx();
}

@After
public void tearDown(TestContext context) {
vertx.close(context.asyncAssertSuccess());
}

@Test
public void testServerClientTlsCommunication(TestContext context) throws IllegalAccessException {
final JsonObject config = getCommonConfig(true);

final HttpServerOptions serverOptions = new HttpServerOptions();
serverOptions.setPort(config.getInteger(Constants.SYS_PORT));

SslConfigurationUtil.configureSslServerOptionsIfEnabled(config, serverOptions);

final HttpServer httpServer = vertx.createHttpServer(serverOptions);
httpServer
.requestHandler(req -> req.response().putHeader(HttpHeaders.CONTENT_TYPE, Constants.TEXT_PLAIN).end(RESPONSE_MESSAGE))
.listen(config.getInteger(Constants.SYS_PORT), getCommonServerHandler(config));

final OkapiClientFactory okapiClientFactory = OkapiClientFactoryInitializer.createInstance(vertx, config);
final OkapiClient okapiClient = okapiClientFactory.getOkapiClient(TENANT);
final WebClientOptions webClientOptions = (WebClientOptions) FieldUtils.readDeclaredField(okapiClient.client, "options", true);

assertTrue(webClientOptions.isSsl());
assertNotNull(webClientOptions.getTrustOptions());

createClientRequest(context, webClientOptions, config);
}

@Test(expected = java.net.ConnectException.class)
public void testFailingServerClientTlsCommunication(TestContext context) throws IllegalAccessException {
final JsonObject config = getCommonConfig(false);

final HttpServerOptions serverOptions = new HttpServerOptions();
serverOptions.setPort(config.getInteger(Constants.SYS_PORT));

SslConfigurationUtil.configureSslServerOptionsIfEnabled(config, serverOptions);

final HttpServer httpServer = vertx.createHttpServer(serverOptions);
httpServer
.requestHandler(req -> req.response().putHeader(HttpHeaders.CONTENT_TYPE, Constants.TEXT_PLAIN).end(RESPONSE_MESSAGE))
.listen(config.getInteger(Constants.SYS_PORT), getCommonServerHandler(config));

final OkapiClientFactory okapiClientFactory = OkapiClientFactoryInitializer.createInstance(vertx, config);
final OkapiClient okapiClient = okapiClientFactory.getOkapiClient(TENANT);
final WebClientOptions webClientOptions = (WebClientOptions) FieldUtils.readDeclaredField(okapiClient.client, "options", true);

assertFalse(webClientOptions.isSsl());
assertNull(webClientOptions.getTrustOptions());

createClientRequest(context, webClientOptions, config);
}

private static io.vertx.core.@NotNull Handler<AsyncResult<HttpServer>> getCommonServerHandler(JsonObject config) {
return http -> logger.info("Server started on port {}", config.getInteger(Constants.SYS_PORT));
}

private static void createClientRequest(TestContext context, WebClientOptions webClientOptions, JsonObject config) {
final WebClient webClient = WebClient.create(vertx, webClientOptions);
webClient.get(config.getInteger(Constants.SYS_PORT), "localhost", "/")
.send()
.onComplete(context.asyncAssertSuccess(response -> {
String message = response.body().toString();
logger.info("WebClient sent message to server port {}, response message: {}", config.getInteger(Constants.SYS_PORT), message);
context.assertEquals(HttpResponseStatus.OK.code(), response.statusCode());
context.assertEquals(RESPONSE_MESSAGE, message);
}));
}

private JsonObject getCommonConfig(boolean enableWebClientSsl) {
int serverPort = TestUtils.getPort();
JsonObject config = new JsonObject().put(Constants.SYS_PORT, serverPort)
.put(Constants.SYS_OKAPI_URL, OKAPI_URL)
.put(Constants.SYS_SECURE_STORE_PROP_FILE, "src/main/resources/ephemeral.properties")
.put(Constants.SYS_LOG_LEVEL, "TRACE")
.put(Constants.SYS_REQUEST_TIMEOUT_MS, 5000)
.put(Constants.SYS_HTTP_SERVER_SSL_ENABLED, true)
.put(Constants.SYS_HTTP_SERVER_KEYSTORE_TYPE, KEYSTORE_TYPE)
.put(Constants.SYS_HTTP_SERVER_KEYSTORE_PATH, KEYSTORE_PATH)
.put(Constants.SYS_HTTP_SERVER_KEYSTORE_PASSWORD, KEYSTORE_PASSWORD);
if (enableWebClientSsl) {
return config
.put(Constants.SYS_WEB_CLIENT_SSL_ENABLED, true)
.put(Constants.SYS_WEB_CLIENT_TRUSTSTORE_TYPE, KEYSTORE_TYPE)
.put(Constants.SYS_WEB_CLIENT_TRUSTSTORE_PATH, TRUST_STORE_PATH)
.put(Constants.SYS_WEB_CLIENT_TRUSTSTORE_PASSWORD, KEYSTORE_PASSWORD);
} else {
return config
.put(Constants.SYS_WEB_CLIENT_SSL_ENABLED, false);
}
}
}
Binary file added src/test/resources/test.keystore 1.bcfks
Binary file not shown.
Binary file added src/test/resources/test.truststore 1.bcfks
Binary file not shown.

0 comments on commit bc84d49

Please sign in to comment.