aboutsummaryrefslogtreecommitdiffstats
path: root/gui-server/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'gui-server/src/test')
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/SpringContextTest.java37
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig1Test.java69
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig2Test.java61
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig3Test.java70
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig4Test.java67
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig5Test.java69
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/filters/ClientSslHeaderFilterTest.java211
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/rest/ApexEditorRestControllerTest.java61
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/rest/ClampRestControllerTest.java161
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/test/util/KeyStoreHelper.java92
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/test/util/X509RequestPostProcessor.java46
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldApplication.java29
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldRestController.java35
-rw-r--r--gui-server/src/test/java/org/onap/policy/gui/server/util/X509CertificateEncoderTest.java47
-rw-r--r--gui-server/src/test/resources/helloworld-keystore.jksbin0 -> 2721 bytes
-rw-r--r--gui-server/src/test/resources/helloworld-truststore.jksbin0 -> 1255 bytes
-rw-r--r--gui-server/src/test/resources/keystore-proxytest.jksbin0 -> 4953 bytes
17 files changed, 1055 insertions, 0 deletions
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/SpringContextTest.java b/gui-server/src/test/java/org/onap/policy/gui/server/SpringContextTest.java
new file mode 100644
index 0000000..7be7694
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/SpringContextTest.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(
+ properties = {
+ "clamp.url=https://clamp-backend:8443/",
+ "clamp.disable-ssl-validation=true"
+ })
+class SpringContextTest {
+
+ @Test
+ @SuppressWarnings("java:S2699")
+ void whenSpringContextIsBootstrapped_thenNoExceptions() {
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig1Test.java b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig1Test.java
new file mode 100644
index 0000000..44e4c46
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig1Test.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.hello.HelloWorldApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * In this test, SSL validation and hostname check are enabled.
+ * Since our keystore cert has a hostname 'helloworld' and our test request is
+ * to localhost, the request will fail with an SSLPeerUnverifiedException, as
+ * the SSL cert name does not match the server name 'localhost'.
+ */
+@SpringBootTest(
+ classes = { HelloWorldApplication.class, ClampRestTemplateConfig.class },
+ properties = {
+ "server.ssl.key-store=file:src/test/resources/helloworld-keystore.jks",
+ "server.ssl.key-store-password=changeit",
+ "server.ssl.trust-store=file:src/test/resources/helloworld-truststore.jks",
+ "server.ssl.trust-store-password=changeit",
+ "clamp.disable-ssl-validation=false",
+ "clamp.disable-ssl-hostname-check=false"
+ },
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class ClampRestTemplateConfig1Test {
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ @Test
+ void testRequestFailsWhenSslHostnameCheckIsEnabled() {
+ var helloUrl = "https://localhost:" + port + "/";
+ Exception e = assertThrows(RestClientException.class,
+ () -> restTemplate.getForEntity(helloUrl, String.class));
+ assertTrue(e.getCause() instanceof SSLPeerUnverifiedException);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig2Test.java b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig2Test.java
new file mode 100644
index 0000000..b8e744c
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig2Test.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.onap.policy.gui.server.test.util.hello.HelloWorldRestController.HELLO_WORLD_STRING;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.hello.HelloWorldApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * In this test, SSL validation is disabled.
+ * The test request should succeed. A trust store has not been supplied in this case.
+ */
+@SpringBootTest(
+ classes = { HelloWorldApplication.class, ClampRestTemplateConfig.class },
+ properties = {
+ "server.ssl.key-store=file:src/test/resources/helloworld-keystore.jks",
+ "server.ssl.key-store-password=changeit",
+ "clamp.disable-ssl-validation=true"
+ },
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class ClampRestTemplateConfig2Test {
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ @Test
+ void testRequestSucceedsWhenSslValidationIsDisabled() {
+ var helloUrl = "https://localhost:" + port + "/";
+ String response = restTemplate.getForObject(helloUrl, String.class);
+ assertEquals(HELLO_WORLD_STRING, response);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig3Test.java b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig3Test.java
new file mode 100644
index 0000000..4636982
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig3Test.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.onap.policy.gui.server.test.util.hello.HelloWorldRestController.HELLO_WORLD_STRING;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.hello.HelloWorldApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * In this test, SSL validation is enabled but hostname check is disabled.
+ * Even though our keystore cert has a hostname 'helloworld' and our test
+ * request is to localhost, the request will succeed as the SSL hostname check
+ * is disabled.
+ */
+@SpringBootTest(
+ classes = { HelloWorldApplication.class, ClampRestTemplateConfig.class },
+ properties = {
+ "server.ssl.key-store=file:src/test/resources/helloworld-keystore.jks",
+ "server.ssl.key-store-password=changeit",
+ "server.ssl.trust-store=file:src/test/resources/helloworld-truststore.jks",
+ "server.ssl.trust-store-password=changeit",
+ "clamp.disable-ssl-validation=false",
+ "clamp.disable-ssl-hostname-check=true"
+ },
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class ClampRestTemplateConfig3Test {
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ /*
+ * In this test, the request will succeed even though the SSL cert name
+ * does not match 'localhost', as SSL hostname verification is disabled.
+ */
+ @Test
+ void testRequestSucceedsWhenSslHostnameCheckIsDisabled() {
+ var helloUrl = "https://localhost:" + port + "/";
+ String response = restTemplate.getForObject(helloUrl, String.class);
+ assertEquals(HELLO_WORLD_STRING, response);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig4Test.java b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig4Test.java
new file mode 100644
index 0000000..f0f222f
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig4Test.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.onap.policy.gui.server.test.util.hello.HelloWorldRestController.HELLO_WORLD_STRING;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.hello.HelloWorldApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * In this test, SSL validation is disabled but hostname check is explicitly
+ * enabled. The expected behaviour is to disable the hostname check if SSL
+ * validation is disabled. We expect the request to succeed even though the
+ * SSL cert name does not match 'localhost', as SSL hostname verification is
+ * implicitly disabled.
+ */
+@SpringBootTest(
+ classes = { HelloWorldApplication.class, ClampRestTemplateConfig.class },
+ properties = {
+ "server.ssl.key-store=file:src/test/resources/helloworld-keystore.jks",
+ "server.ssl.key-store-password=changeit",
+ "server.ssl.trust-store=file:src/test/resources/helloworld-truststore.jks",
+ "server.ssl.trust-store-password=changeit",
+ "clamp.disable-ssl-validation=true",
+ "clamp.disable-ssl-hostname-check=false"
+ },
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class ClampRestTemplateConfig4Test {
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ @Test
+ void testHostnameCheckIsDisabledWhenSslValidationIsDisabled() {
+ var helloUrl = "https://localhost:" + port + "/";
+ String response = restTemplate.getForObject(helloUrl, String.class);
+ assertEquals(HELLO_WORLD_STRING, response);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig5Test.java b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig5Test.java
new file mode 100644
index 0000000..cc23de5
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/config/ClampRestTemplateConfig5Test.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.config;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import javax.net.ssl.SSLPeerUnverifiedException;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.hello.HelloWorldApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * In this test, we verify that SSL validation and hostname check are enabled
+ * by default. Thus we do not explicitly set the Spring properties
+ * clamp.disable-ssl-validation and clamp.disable-ssl-hostname-check.
+ * Since our keystore cert has a hostname 'helloworld' and our test request is
+ * to localhost, the request will fail with an SSLPeerUnverifiedException, as
+ * the SSL cert name does not match the server name 'localhost'.
+ */
+@SpringBootTest(
+ classes = { HelloWorldApplication.class, ClampRestTemplateConfig.class },
+ properties = {
+ "server.ssl.key-store=file:src/test/resources/helloworld-keystore.jks",
+ "server.ssl.key-store-password=changeit",
+ "server.ssl.trust-store=file:src/test/resources/helloworld-truststore.jks",
+ "server.ssl.trust-store-password=changeit",
+ },
+ webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+class ClampRestTemplateConfig5Test {
+
+ @LocalServerPort
+ private int port;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ @Test
+ void testSslValidationIsEnabledByDefault() {
+ var helloUrl = "https://localhost:" + port + "/";
+ Exception e = assertThrows(RestClientException.class,
+ () -> restTemplate.getForEntity(helloUrl, String.class));
+ assertTrue(e.getCause() instanceof SSLPeerUnverifiedException);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/filters/ClientSslHeaderFilterTest.java b/gui-server/src/test/java/org/onap/policy/gui/server/filters/ClientSslHeaderFilterTest.java
new file mode 100644
index 0000000..5fc026d
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/filters/ClientSslHeaderFilterTest.java
@@ -0,0 +1,211 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.filters;
+
+import static org.apache.commons.collections4.CollectionUtils.isEqualCollection;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.onap.policy.gui.server.filters.ClientSslHeaderFilter.SSL_CERT_HEADER_NAME;
+import static org.onap.policy.gui.server.filters.ClientSslHeaderFilter.X509_ATTRIBUTE_NAME;
+import static org.onap.policy.gui.server.util.X509CertificateEncoder.urlDecodeCert;
+
+import java.io.IOException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.onap.policy.gui.server.test.util.KeyStoreHelper;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+class ClientSslHeaderFilterTest {
+
+ /*
+ * If the client does not supply an SSL cert, the filter should not set
+ * the X-SSL-Cert header.
+ */
+ @Test
+ void testNoClientCert_noHeader() throws ServletException, IOException {
+ // Create a request without client SSL cert.
+ HttpServletRequest inRequest = new MockHttpServletRequest();
+
+ // Apply the filter.
+ HttpServletRequest outRequest = applyRequestFilter(inRequest);
+
+ // The modified request should not contain cert header.
+ assertFalse(containsCertHeader(outRequest.getHeaderNames()));
+ assertNull(outRequest.getHeader(SSL_CERT_HEADER_NAME));
+ assertEquals(Collections.emptyEnumeration(), outRequest.getHeaders(SSL_CERT_HEADER_NAME));
+ }
+
+ /*
+ * If the client does supply an SSL cert, the filter should set the
+ * X-SSL-Cert header with the encoded SSL cert.
+ */
+ @Test
+ void testValidClientCert_hasHeader() throws Exception {
+ // Load valid cert from key store.
+ X509Certificate validCert = KeyStoreHelper.loadValidCert();
+
+ // Create a request with a valid client SSL cert.
+ MockHttpServletRequest inRequest = new MockHttpServletRequest();
+ inRequest.setAttribute(X509_ATTRIBUTE_NAME, new X509Certificate[] { validCert });
+
+ // Apply the filter.
+ HttpServletRequest outRequest = applyRequestFilter(inRequest);
+
+ // The modified request should contain a cert header.
+ assertTrue(containsCertHeader(outRequest.getHeaderNames()));
+
+ // Check if the cert header parses back to the original cert.
+ String headerValue = outRequest.getHeader(SSL_CERT_HEADER_NAME);
+ assertEquals(validCert, urlDecodeCert(headerValue));
+
+ // Verify the getHeaders method also returns cert.
+ assertEquals(headerValue, outRequest.getHeaders(SSL_CERT_HEADER_NAME).nextElement());
+ }
+
+ /*
+ * If the client supplies an expired SSL cert, the filter should not set
+ * the X-SSL-Cert header.
+ */
+ @Test
+ void testExpiredClientCert_noHeader() throws Exception {
+ // Load expired cert from key store.
+ X509Certificate expiredCert = KeyStoreHelper.loadExpiredCert();
+
+ // Create a request with an expired client SSL cert.
+ MockHttpServletRequest inRequest = new MockHttpServletRequest();
+ inRequest.setAttribute(X509_ATTRIBUTE_NAME, new X509Certificate[] { expiredCert });
+
+ // Apply the filter.
+ HttpServletRequest outRequest = applyRequestFilter(inRequest);
+
+ // The modified request should not contain a cert header.
+ assertFalse(containsCertHeader(outRequest.getHeaderNames()));
+ assertNull(outRequest.getHeader(SSL_CERT_HEADER_NAME));
+ assertEquals(Collections.emptyEnumeration(), outRequest.getHeaders(SSL_CERT_HEADER_NAME));
+ }
+
+ /*
+ * This test is needed to prevent a security vulnerability where a
+ * malicious user does not authenticate using client cert, but defines the
+ * X-SSL-Cert header themselves, thus gaining access without having the
+ * corresponding private key.
+ * We thus test that an incoming X-SSL-Cert header is sanitized.
+ */
+ @Test
+ void existingCertHeaderIsSanitized() throws Exception {
+ // Create a request with X-SSL-Cert header predefined.
+ MockHttpServletRequest inRequest = new MockHttpServletRequest();
+ inRequest.addHeader(SSL_CERT_HEADER_NAME, "somevalue");
+
+ // Apply the filter.
+ HttpServletRequest outRequest = applyRequestFilter(inRequest);
+
+ // The modified request should not contain a cert header.
+ assertFalse(containsCertHeader(outRequest.getHeaderNames()));
+ assertNull(outRequest.getHeader(SSL_CERT_HEADER_NAME));
+ assertEquals(Collections.emptyEnumeration(), outRequest.getHeaders(SSL_CERT_HEADER_NAME));
+ }
+
+ /*
+ * This test verifies that existing HTTP headers are preserved
+ * (including multi-value headers).
+ */
+ @Test
+ void otherHeadersAreStillAccessible() throws Exception {
+ // Load valid cert from key store.
+ X509Certificate validCert = KeyStoreHelper.loadValidCert();
+
+ // Create a request with a valid client SSL cert and some existing headers.
+ MockHttpServletRequest inRequest = new MockHttpServletRequest();
+ inRequest.setAttribute(X509_ATTRIBUTE_NAME, new X509Certificate[] { validCert });
+ inRequest.addHeader("User-Agent", "Jupiter");
+ inRequest.addHeader("Accept-Language", "en-US");
+ inRequest.addHeader("Accept-Language", "en-IE");
+
+ // Apply the filter.
+ HttpServletRequest outRequest = applyRequestFilter(inRequest);
+
+ // The modified request contains the new cert header and the existing headers.
+ assertTrue(
+ isEqualCollection(
+ List.of("Accept-Language", "User-Agent", SSL_CERT_HEADER_NAME),
+ Collections.list(outRequest.getHeaderNames())));
+
+ // Verify getHeader method returns correct value.
+ String userAgent = outRequest.getHeader("User-Agent");
+ assertEquals("Jupiter", userAgent);
+
+ // Verify getHeaders method returns correct values.
+ Enumeration<String> acceptLanguages = outRequest.getHeaders("Accept-Language");
+ assertEquals("en-US", acceptLanguages.nextElement());
+ assertEquals("en-IE", acceptLanguages.nextElement());
+ assertFalse(acceptLanguages.hasMoreElements());
+ }
+
+ /**
+ * Apply the ClientSslToHeaderFilter to the input request,
+ * and return the modified request.
+ */
+ private HttpServletRequest applyRequestFilter(HttpServletRequest request) throws ServletException, IOException {
+ HttpServletResponse response = new MockHttpServletResponse();
+
+ // The filter calls filterChain::doFilter after processing the request,
+ // so capture the HttpServletRequest argument from filterChain::doFilter.
+ FilterChain filterChain = mock(FilterChain.class);
+ ArgumentCaptor<HttpServletRequest> requestCaptor = ArgumentCaptor.forClass(HttpServletRequest.class);
+ doNothing().when(filterChain).doFilter(requestCaptor.capture(), eq(response));
+
+ // Apply the filter.
+ Filter filter = new ClientSslHeaderFilter();
+ filter.doFilter(request, response, filterChain);
+
+ // Return the modified HttpServletRequest.
+ return requestCaptor.getValue();
+ }
+
+ /**
+ * Check if an Enumeration of header names contains the certificate header.
+ * Note HTTP header names are case insensitive.
+ */
+ private boolean containsCertHeader(Enumeration<String> headers) {
+ while (headers.hasMoreElements()) {
+ if (headers.nextElement().equalsIgnoreCase(SSL_CERT_HEADER_NAME)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/rest/ApexEditorRestControllerTest.java b/gui-server/src/test/java/org/onap/policy/gui/server/rest/ApexEditorRestControllerTest.java
new file mode 100644
index 0000000..4cfd994
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/rest/ApexEditorRestControllerTest.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.rest;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.web.servlet.MockMvc;
+
+@SpringBootTest(
+ properties = {
+ "clamp.url=https://clamp-backend:8443/",
+ "clamp.disable-ssl-validation=true"
+ })
+@AutoConfigureMockMvc
+class ApexEditorRestControllerTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ void testStaticContentUrls() throws Exception {
+ mvc.perform(get("/apex-editor/"))
+ .andExpect(status().isOk())
+ .andExpect(forwardedUrl("/apex-editor/index.html"));
+
+ mvc.perform(get("/apex-editor"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(redirectedUrl("/apex-editor/"));
+ }
+
+ @Test
+ void testApexEditorRestForwarding() throws Exception {
+ mvc.perform(get("/apex-editor/policy/gui/v1/apex/editor/-1/Session/Create"))
+ .andExpect(forwardedUrl("/policy/gui/v1/apex/editor/-1/Session/Create"));
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/rest/ClampRestControllerTest.java b/gui-server/src/test/java/org/onap/policy/gui/server/rest/ClampRestControllerTest.java
new file mode 100644
index 0000000..fb3e843
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/rest/ClampRestControllerTest.java
@@ -0,0 +1,161 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.rest;
+
+import static org.onap.policy.gui.server.filters.ClientSslHeaderFilter.SSL_CERT_HEADER_NAME;
+import static org.onap.policy.gui.server.test.util.X509RequestPostProcessor.x509;
+import static org.onap.policy.gui.server.util.X509CertificateEncoder.urlEncodeCert;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.security.cert.X509Certificate;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.KeyStoreHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.web.client.MockRestServiceServer;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootTest(
+ properties = {
+ "clamp.url=https://clamp-backend:8443/",
+ "clamp.disable-ssl-validation=true"
+ })
+@AutoConfigureMockMvc
+class ClampRestControllerTest {
+
+ @Autowired
+ private MockMvc mvc;
+
+ @Autowired
+ @Qualifier("clampRestTemplate")
+ private RestTemplate restTemplate;
+
+ private MockRestServiceServer mockServer;
+
+ @BeforeEach
+ public void init() {
+ mockServer = MockRestServiceServer.createServer(restTemplate);
+ }
+
+ @Test
+ void testStaticContentUrls() throws Exception {
+ mvc.perform(get("/clamp/"))
+ .andExpect(status().isOk())
+ .andExpect(forwardedUrl("/clamp/index.html"));
+
+ mvc.perform(get("/clamp"))
+ .andExpect(status().is3xxRedirection())
+ .andExpect(redirectedUrl("/clamp/"));
+ }
+
+ /*
+ * This is a happy path test to verify that calls to /clamp/restservices/**
+ * are relayed to the clamp backend, and that the backend receives the
+ * client certificate encoded in a header. More extensive tests of the
+ * certificate cert filter are in ClientSslHeaderFilterTest.
+ */
+ @Test
+ void testClampProxyWithClientCert() throws Exception {
+ X509Certificate cert = KeyStoreHelper.loadValidCert();
+
+ mockServer.expect(
+ requestTo("https://clamp-backend:8443/restservices/junit/test"))
+ .andExpect(header(SSL_CERT_HEADER_NAME, urlEncodeCert(cert)))
+ .andRespond(withStatus(HttpStatus.OK).body("admin"));
+
+ mvc.perform(
+ get("/clamp/restservices/junit/test")
+ .with(x509(cert)))
+ .andExpect(status().isOk())
+ .andExpect(content().string("admin"));
+
+ mockServer.verify();
+ }
+
+ /*
+ * This test verifies that HTTP headers are preserved for requests to the
+ * clamp backend (including multi-value headers).
+ */
+ @Test
+ void verifyClampProxyPassesHeaders() throws Exception {
+ // Single value header
+ final String userAgent = "User-Agent";
+ final String userAgentValue = "JUnit";
+ // Multi value header
+ final String acceptLanguage = "Accept-Language";
+ final String enUs = "en-US";
+ final String enIe = "en-IE";
+
+ mockServer.expect(
+ requestTo("https://clamp-backend:8443/restservices/junit/test"))
+ .andExpect(method(HttpMethod.GET))
+ .andExpect(header(userAgent, userAgentValue))
+ .andExpect(header(acceptLanguage, enUs, enIe))
+ .andRespond(withStatus(HttpStatus.OK));
+
+ HttpHeaders requestHeaders = new HttpHeaders();
+ requestHeaders.set(userAgent, userAgentValue);
+ requestHeaders.add(acceptLanguage, enUs);
+ requestHeaders.add(acceptLanguage, enIe);
+ mvc.perform(
+ get("/clamp/restservices/junit/test")
+ .headers(requestHeaders))
+ .andExpect(status().isOk());
+
+ mockServer.verify();
+ }
+
+ /*
+ * This test verifies that error messages from the clamp backend are
+ * delivered to the client (as opposed to 500 "Internal Server Error").
+ */
+ @Test
+ void verifyClampProxyReturnsBackendErrorCode() throws Exception {
+ final String errorMessage = "This appliance cannot brew coffee";
+
+ mockServer.expect(
+ requestTo("https://clamp-backend:8443/restservices/coffee"))
+ .andRespond(withStatus(HttpStatus.I_AM_A_TEAPOT).body(errorMessage));
+
+ mvc.perform(
+ post("/clamp/restservices/coffee"))
+ .andExpect(status().is(HttpStatus.I_AM_A_TEAPOT.value()))
+ .andExpect(content().string(errorMessage));
+
+ mockServer.verify();
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/test/util/KeyStoreHelper.java b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/KeyStoreHelper.java
new file mode 100644
index 0000000..a4aabb8
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/KeyStoreHelper.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.test.util;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.X509Certificate;
+import org.junit.jupiter.api.function.Executable;
+
+public class KeyStoreHelper {
+ /*
+ * The proxy test keystore contains certs with:
+ * - alias "valid": self-signed cert which expires circa year 2050
+ * - alias "expired": self-signed cert which expired in year 2000
+ */
+ private static final String KEY_STORE_PATH = "src/test/resources/keystore-proxytest.jks";
+ private static final String KEY_STORE_PASSWORD = "changeit";
+ private static final String KEY_STORE_TYPE = "JKS";
+ private static final String CERT_ALIAS_VALID = "valid";
+ private static final String CERT_ALIAS_EXPIRED = "expired";
+
+ /**
+ * Load a valid certificate from the test keystore.
+ */
+ public static X509Certificate loadValidCert() throws CouldNotLoadCertificateException {
+ X509Certificate cert = loadCertFromKeyStore(CERT_ALIAS_VALID);
+ assertDoesNotThrow((Executable) cert::checkValidity);
+ return cert;
+ }
+
+ /**
+ * Load an expired certificate from the test keystore.
+ */
+ public static X509Certificate loadExpiredCert() throws CouldNotLoadCertificateException {
+ X509Certificate cert = loadCertFromKeyStore(CERT_ALIAS_EXPIRED);
+ assertThrows(CertificateExpiredException.class, cert::checkValidity);
+ return cert;
+ }
+
+ /**
+ * Load a certificate with given alias from the test keystore.
+ */
+ private static X509Certificate loadCertFromKeyStore(String certAlias) throws CouldNotLoadCertificateException {
+ try {
+ KeyStore ks = KeyStore.getInstance(KEY_STORE_TYPE);
+ ks.load(new FileInputStream(KEY_STORE_PATH), KEY_STORE_PASSWORD.toCharArray());
+ X509Certificate cert = (X509Certificate) ks.getCertificate(certAlias);
+ if (cert == null) {
+ throw new CouldNotLoadCertificateException("Alias does not exist or does not contain a certificate.");
+ }
+ return cert;
+ } catch (Exception e) {
+ throw new CouldNotLoadCertificateException(
+ "Could not load cert with alias '" + certAlias + "' from test keystore.", e);
+ }
+ }
+
+ /**
+ * Exception class for KeyStoreHelper methods.
+ */
+ public static class CouldNotLoadCertificateException extends java.lang.Exception {
+ protected CouldNotLoadCertificateException(String errorMessage) {
+ super(errorMessage);
+ }
+
+ protected CouldNotLoadCertificateException(String errorMessage, Throwable err) {
+ super(errorMessage, err);
+ }
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/test/util/X509RequestPostProcessor.java b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/X509RequestPostProcessor.java
new file mode 100644
index 0000000..b1ef4a1
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/X509RequestPostProcessor.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.test.util;
+
+import java.security.cert.X509Certificate;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.test.web.servlet.request.RequestPostProcessor;
+
+/**
+ * X509RequestPostProcessor is a test helper class for use with Spring MockMvc.
+ * It allows setting X509 certificates to a MockHttpServletRequest.
+ */
+public final class X509RequestPostProcessor implements RequestPostProcessor {
+ private final X509Certificate[] certificates;
+
+ public X509RequestPostProcessor(X509Certificate... certificates) {
+ this.certificates = certificates;
+ }
+
+ public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
+ request.setAttribute("javax.servlet.request.X509Certificate", this.certificates);
+ return request;
+ }
+
+ public static RequestPostProcessor x509(X509Certificate... certificates) {
+ return new X509RequestPostProcessor(certificates);
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldApplication.java b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldApplication.java
new file mode 100644
index 0000000..e584665
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldApplication.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.test.util.hello;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+// This class is used in tests for ClampRestTemplateConfig.
+@SpringBootApplication
+public class HelloWorldApplication {
+
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldRestController.java b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldRestController.java
new file mode 100644
index 0000000..71bd483
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/test/util/hello/HelloWorldRestController.java
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.test.util.hello;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+// This class is used in tests for ClampRestTemplateConfig.
+@RestController
+public class HelloWorldRestController {
+ public static final String HELLO_WORLD_STRING = "Hello, World";
+
+ @RequestMapping("/")
+ public String greeting() {
+ return HELLO_WORLD_STRING;
+ }
+}
diff --git a/gui-server/src/test/java/org/onap/policy/gui/server/util/X509CertificateEncoderTest.java b/gui-server/src/test/java/org/onap/policy/gui/server/util/X509CertificateEncoderTest.java
new file mode 100644
index 0000000..28b1217
--- /dev/null
+++ b/gui-server/src/test/java/org/onap/policy/gui/server/util/X509CertificateEncoderTest.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.gui.server.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.gui.server.test.util.KeyStoreHelper;
+
+class X509CertificateEncoderTest {
+
+ @Test
+ void testPemEncoder() throws KeyStoreHelper.CouldNotLoadCertificateException, CertificateException {
+ X509Certificate loadedCert = KeyStoreHelper.loadValidCert();
+ String pem = X509CertificateEncoder.getPemFromCert(loadedCert);
+ X509Certificate certFromPem = X509CertificateEncoder.getCertFromPem(pem);
+ assertEquals(loadedCert, certFromPem);
+ }
+
+ @Test
+ void testUrlEncoder() throws KeyStoreHelper.CouldNotLoadCertificateException, CertificateException {
+ X509Certificate loadedCert = KeyStoreHelper.loadValidCert();
+ String encodedCert = X509CertificateEncoder.urlEncodeCert(loadedCert);
+ X509Certificate decodedCert = X509CertificateEncoder.urlDecodeCert(encodedCert);
+ assertEquals(loadedCert, decodedCert);
+ }
+}
diff --git a/gui-server/src/test/resources/helloworld-keystore.jks b/gui-server/src/test/resources/helloworld-keystore.jks
new file mode 100644
index 0000000..c2f1a0e
--- /dev/null
+++ b/gui-server/src/test/resources/helloworld-keystore.jks
Binary files differ
diff --git a/gui-server/src/test/resources/helloworld-truststore.jks b/gui-server/src/test/resources/helloworld-truststore.jks
new file mode 100644
index 0000000..64c123e
--- /dev/null
+++ b/gui-server/src/test/resources/helloworld-truststore.jks
Binary files differ
diff --git a/gui-server/src/test/resources/keystore-proxytest.jks b/gui-server/src/test/resources/keystore-proxytest.jks
new file mode 100644
index 0000000..c261084
--- /dev/null
+++ b/gui-server/src/test/resources/keystore-proxytest.jks
Binary files differ