[java-idp-integration-tests] branch main updated: Add consent test with a Postgres storage service
Tom Zeller
tzeller at dragonacea.biz
Thu Oct 3 02:45:37 UTC 2024
This is an automated email from the git hooks/post-receive script.
tzeller pushed a commit to branch main
in repository java-idp-integration-tests.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-integration-tests.git;a=commit;h=399b603e14cd3030f6ed84d3e997ed2821353375
The following commit(s) were added to refs/heads/main by this push:
new 399b603 Add consent test with a Postgres storage service
399b603 is described below
commit 399b603e14cd3030f6ed84d3e997ed2821353375
Author: Tom Zeller <tzeller at dragonacea.biz>
AuthorDate: Wed Oct 2 21:45:27 2024 -0500
Add consent test with a Postgres storage service
https://shibboleth.atlassian.net/browse/IDP-2323
---
pom.xml | 33 ++++
.../shibboleth/idp/integration/tests/BaseTest.java | 111 +++++++++++
.../tests/clientstorage/ClientStorageTest.java | 46 +----
.../tests/saml2/PostgresConsentTest.java | 218 +++++++++++++++++++++
.../idp/integration/tests/postgres/create-table.sh | 8 +
.../integration/tests/postgres/docker-compose.yml | 15 ++
.../idp/integration/tests/postgres/global.xml | 9 +
7 files changed, 399 insertions(+), 41 deletions(-)
diff --git a/pom.xml b/pom.xml
index d5ad865..02c1371 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,12 @@
<!-- Apache Commons Net -->
<commons-net.version>3.11.1</commons-net.version>
+ <!-- PostgreSQL driver -->
+ <postgresql.version>42.7.4</postgresql.version>
+
+ <!-- HikariCP driver -->
+ <hikaricp.version>5.1.0</hikaricp.version>
+
<!-- Directory where the IdP and Servlet container are unpacked -->
<test-distributions.directory>${project.basedir}/test-distributions</test-distributions.directory>
@@ -152,6 +158,33 @@
<scope>test</scope>
</dependency>
+ <!-- Testcontainers Postgres support : consent storage test -->
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>postgresql</artifactId>
+ <version>${testcontainers.version}</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <!-- Postgres JDBC driver : consent storage test -->
+ <dependency>
+ <groupId>org.postgresql</groupId>
+ <artifactId>postgresql</artifactId>
+ <version>${postgresql.version}</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <!-- HikariCP : consent storage test -->
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ <version>${hikaricp.version}</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+
</dependencies>
<build>
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/BaseTest.java b/src/test/java/net/shibboleth/idp/integration/tests/BaseTest.java
index 5958d26..5e4e0ca 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/BaseTest.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/BaseTest.java
@@ -3445,4 +3445,115 @@ public abstract class BaseTest {
public static boolean isChrome() {
return System.getProperty("SELENIUM_BROWSER").toLowerCase().equals("chrome");
}
+
+ /**
+ * Add testbed storage servlet to IdP.
+ *
+ * @throws IOException
+ * if an error occurs
+ */
+ public void setUpStorageServlet() throws IOException {
+
+ final Path pathToEditWebapp = pathToIdPHome.resolve("edit-webapp").toAbsolutePath();
+ log.debug("Path to edit-webapp '{}'", pathToEditWebapp);
+ Assert.assertTrue(pathToEditWebapp.toFile().exists(), "Path to edit-webapp " + pathToEditWebapp + " should exist");
+
+ // Extract web.xml from idp.war
+ if (isWindows()) {
+ logProcess(Runtime.getRuntime().exec("jar -xvf ..\\war\\idp.war WEB-INF\\web.xml", null, pathToEditWebapp.toFile()), "jar :");
+ } else {
+ logProcess(Runtime.getRuntime().exec("jar -xvf ../war/idp.war WEB-INF/web.xml", null, pathToEditWebapp.toFile()), "jar :");
+ }
+
+ final Path pathToCustomWebXML = pathToEditWebapp.resolve("WEB-INF").resolve("web.xml");
+ log.debug("Path to custom web.xml '{}'", pathToCustomWebXML);
+ Assert.assertTrue(pathToCustomWebXML.toFile().exists(), "Path to web.xml " + pathToCustomWebXML + " should exist");
+
+ final String oldText = "</web-app>";
+
+ final StringBuilder newText = new StringBuilder();
+ newText.append("\n");
+ newText.append("<!-- The /storage app space. Interact with storage services via HTTP. -->\n");
+ newText.append("<servlet>\n");
+ newText.append(" <servlet-name>storage</servlet-name>\n");
+ newText.append(" <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>\n");
+ newText.append(" <init-param>\n");
+ newText.append(" <param-name>contextConfigLocation</param-name>\n");
+ newText.append(" <param-value>classpath:/system/conf/storage-context.xml</param-value>\n");
+ newText.append(" </init-param>\n");
+ newText.append(" <load-on-startup>1</load-on-startup>\n");
+ newText.append("</servlet>\n");
+ newText.append("<servlet-mapping>\n");
+ newText.append(" <servlet-name>storage</servlet-name>\n");
+ newText.append(" <url-pattern>/storage/*</url-pattern>\n");
+ newText.append("</servlet-mapping>\n");
+ newText.append("</web-app>\n");
+
+ replaceFile(pathToCustomWebXML, oldText, newText.toString());
+
+ buildWAR();
+ }
+
+ /**
+ * Copy Maven dependency to edit-webapp/WEB-INF/lib.
+ *
+ * @param groupId
+ * groupId of Maven dependency
+ * @param artifactId
+ * artifactId of Maven dependency
+ * @throws IOException
+ * if an error occurs
+ */
+ public void copyDependency(@Nonnull final String groupId, @Nonnull final String artifactId) throws IOException {
+
+ final Path pathToEditWebappWebInfLib = pathToIdPHome.resolve(Paths.get("edit-webapp", "WEB-INF", "lib"));
+
+ Files.createDirectories(pathToEditWebappWebInfLib);
+
+ final String[] commands = new String[] { //
+ "mvn", //
+ "dependency:copy-dependencies", //
+ "-DincludeGroupIds=" + groupId, //
+ "-DincludeArtifactIds=" + artifactId, //
+ "-DoutputDirectory=" + pathToEditWebappWebInfLib.toAbsolutePath().toString() };
+
+ final Process process = new ProcessBuilder() //
+ .command(commands)
+ .redirectErrorStream(true)
+ .start();
+
+ logProcess(process, "Copy dependency :");
+ }
+
+ /**
+ * Download a Maven artifact to edit-webapp/WEB-INF/lib.
+ *
+ * @param artifact
+ * string of the form
+ * groupId:artifactId:version[:packaging[:classifier]] for example,
+ * "org.postgresql:postgresql:LATEST"
+ * @throws IOException
+ * if an error occurs
+ */
+ public void downloadArtifact(@Nonnull final String artifact) throws IOException {
+
+ final Path pathToEditWebappWebInfLib = pathToIdPHome.resolve(Paths.get("edit-webapp", "WEB-INF", "lib"));
+
+ Files.createDirectories(pathToEditWebappWebInfLib);
+
+ final String[] commands = new String[] { //
+ "mvn", //
+ "dependency:copy", //
+ "-Dartifact=" + artifact, //
+ "-Dtransitive=false", //
+ "-DoutputDirectory=" + pathToEditWebappWebInfLib.toAbsolutePath().toString() };
+
+ final Process process = new ProcessBuilder() //
+ .command(commands)
+ .redirectErrorStream(true)
+ .start();
+
+ logProcess(process, "Download artifact :");
+ }
+
}
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/clientstorage/ClientStorageTest.java b/src/test/java/net/shibboleth/idp/integration/tests/clientstorage/ClientStorageTest.java
index a83960b..432c28d 100644
--- a/src/test/java/net/shibboleth/idp/integration/tests/clientstorage/ClientStorageTest.java
+++ b/src/test/java/net/shibboleth/idp/integration/tests/clientstorage/ClientStorageTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.integration.tests.clientstorage;
+import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
@@ -69,49 +70,12 @@ public class ClientStorageTest extends BaseTest {
/**
* Add testbed storage servlet to IdP.
*
- * @throws Exception if an error occurs
+ * @throws IOException
+ * if an error occurs
*/
@BeforeClass(enabled = true, dependsOnMethods = {"setUpIdPPaths"})
- public void setUpStorageServlet() throws Exception {
-
- final Path pathToEditWebapp = pathToIdPHome.resolve("edit-webapp").toAbsolutePath();
- log.debug("Path to edit-webapp '{}'", pathToEditWebapp);
- Assert.assertTrue(pathToEditWebapp.toFile().exists(), "Path to edit-webapp " + pathToEditWebapp + " should exist");
-
- // Extract web.xml from idp.war
- if (isWindows()) {
- logProcess(Runtime.getRuntime().exec("jar -xvf ..\\war\\idp.war WEB-INF\\web.xml", null, pathToEditWebapp.toFile()), "jar :");
- } else {
- logProcess(Runtime.getRuntime().exec("jar -xvf ../war/idp.war WEB-INF/web.xml", null, pathToEditWebapp.toFile()), "jar :");
- }
-
- final Path pathToCustomWebXML = pathToEditWebapp.resolve("WEB-INF").resolve("web.xml");
- log.debug("Path to custom web.xml '{}'", pathToCustomWebXML);
- Assert.assertTrue(pathToCustomWebXML.toFile().exists(), "Path to web.xml " + pathToCustomWebXML + " should exist");
-
- final String oldText = "</web-app>";
-
- final StringBuilder newText = new StringBuilder();
- newText.append("\n");
- newText.append("<!-- The /storage app space. Interact with storage services via HTTP. -->\n");
- newText.append("<servlet>\n");
- newText.append(" <servlet-name>storage</servlet-name>\n");
- newText.append(" <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>\n");
- newText.append(" <init-param>\n");
- newText.append(" <param-name>contextConfigLocation</param-name>\n");
- newText.append(" <param-value>classpath:/system/conf/storage-context.xml</param-value>\n");
- newText.append(" </init-param>\n");
- newText.append(" <load-on-startup>1</load-on-startup>\n");
- newText.append("</servlet>\n");
- newText.append("<servlet-mapping>\n");
- newText.append(" <servlet-name>storage</servlet-name>\n");
- newText.append(" <url-pattern>/storage/*</url-pattern>\n");
- newText.append("</servlet-mapping>\n");
- newText.append("</web-app>\n");
-
- replaceFile(pathToCustomWebXML, oldText, newText.toString());
-
- buildWAR();
+ public void setUpStorageServlet() throws IOException {
+ super.setUpStorageServlet();
}
/**
diff --git a/src/test/java/net/shibboleth/idp/integration/tests/saml2/PostgresConsentTest.java b/src/test/java/net/shibboleth/idp/integration/tests/saml2/PostgresConsentTest.java
new file mode 100644
index 0000000..5ce4713
--- /dev/null
+++ b/src/test/java/net/shibboleth/idp/integration/tests/saml2/PostgresConsentTest.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.
+ */
+
+package net.shibboleth.idp.integration.tests.saml2;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.integration.tests.util.testng.annotation.LinuxOnly;
+
+/** Test consent with a Postgres storage service. */
+public class PostgresConsentTest extends AbstractSAML2IntegrationTest {
+
+ /** Class logger. */
+ @Nonnull
+ private final Logger log = LoggerFactory.getLogger(PostgresConsentTest.class);
+
+ /** Postgres container. */
+ private PostgreSQLContainer<?> postgresContainer;
+
+ @BeforeClass
+ public void setUpURLs() throws Exception {
+
+ startFlowURLPath = "/sp/SAML2/InitSSO/Redirect";
+
+ loginPageURLPath = "/idp/profile/SAML2/Redirect/SSO";
+
+ responsePageURLPath = "/sp/SAML2/POST/ACS";
+
+ isPassiveRequestURLPath = "/sp/SAML2/InitSSO/Passive";
+
+ forceAuthnRequestURLPath = "/sp/SAML2/InitSSO/ForceAuthn";
+
+ idpLogoutURLPath = "/idp/profile/SAML2/Redirect/SLO";
+
+ spLogoutURLPath = "/sp/SAML2/Redirect/SLO";
+
+ logoutTransientIDInputID = "InitSLO_Redirect";
+ }
+
+ /**
+ * Set up Postgres storage service.
+ *
+ * Install JDBC Plugin.
+ *
+ * Add testbed storage servlet to the IdP.
+ *
+ * Add Postgres and HikariCP drivers to the IdP.
+ *
+ * @throws IOException
+ * if an error occurs
+ */
+ @BeforeClass
+ public void setUpPostgresStorageService() throws IOException {
+
+ installPlugin("net.shibboleth.plugin.storage.jdbc");
+
+ setUpStorageServlet();
+
+ downloadPostgresqlDriver();
+
+ downloadHikariCPDriver();
+
+ buildWAR();
+
+ enablePostgresStorageService();
+
+ replaceIdPProperty("idp.consent.StorageService", "my.JDBCStorageService");
+ }
+
+ /**
+ * Download latest Postgres driver to edit-webapp/WEB-INF/lib.
+ *
+ * @throws IOException
+ * if an error occurs
+ */
+ public void downloadPostgresqlDriver() throws IOException {
+ copyDependency("org.postgresql", "postgresql");
+ }
+
+ /**
+ * Download latest HikariCP driver to edit-webapp/WEB-INF/lib.
+ *
+ * @throws IOException
+ * if an error occurs
+ */
+ public void downloadHikariCPDriver() throws IOException {
+ copyDependency("com.zaxxer", "HikariCP");
+ }
+
+ /**
+ * Enable JDBC storage using Postgres and HikariCP.
+ *
+ * Enables beans from
+ * "/net/shibboleth/idp/integration/tests/postgres/global.xml".
+ *
+ * @throws IOException
+ * if an error occurs
+ * @throws URISyntaxException
+ * if an error occurs
+ */
+ public void enablePostgresStorageService() throws IOException {
+ try {
+ final Path pathToGlobalXML = pathToIdPHome.resolve(Paths.get("conf", "global.xml"));
+
+ assert pathToGlobalXML.toAbsolutePath().toFile().exists() : "Path to global.xml not found";
+
+ final String oldText = "</beans>";
+
+ final String resourcePath = "/net/shibboleth/idp/integration/tests/postgres/global.xml";
+
+ final Path pathToSnippetForGlobalXML = Paths.get(this.getClass().getResource(resourcePath).toURI());
+
+ final String newText = Files.readString(pathToSnippetForGlobalXML);
+
+ replaceFile(pathToGlobalXML, oldText, newText + "\n" + oldText);
+
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Start Postgres container.
+ *
+ * Creates "StorageRecords" table.
+ *
+ * @return the JDBC URL to connect to the Postgres container
+ * @throws IOException
+ */
+ @BeforeMethod()
+ public String startPostgres() throws IOException {
+
+ final String initScriptPath = "net/shibboleth/idp/integration/tests/postgres/create-table.sh";
+
+ postgresContainer = new PostgreSQLContainer<>("postgres").withInitScript(initScriptPath);
+
+ log.debug("{} Starting Postgres ...");
+ postgresContainer.start();
+ log.debug("{} Started Postgres : '{}'", postgresContainer.getContainerName());
+
+ final String jdbcUrl = postgresContainer.getJdbcUrl();
+ log.info("{} Postgres JDBC URL : '{}'", jdbcUrl);
+
+ replaceIdPHomeFile(Paths.get("conf", "global.xml"), "jdbc:postgresql://localhost:\\d+/test\\?loggerLevel=OFF", jdbcUrl);
+
+ return jdbcUrl;
+ }
+
+ /**
+ * Stop Postgres.
+ */
+ @AfterMethod()
+ public void stopPostgres() {
+ if (postgresContainer != null) {
+ log.debug("{} Stopping Postgres ...");
+ postgresContainer.stop();
+ log.debug("{} Postgres stopped");
+ }
+ }
+
+ @Test
+ @LinuxOnly
+ public void testSSOReleaseAllAttributes() throws Exception {
+ super.testSSOReleaseAllAttributes();
+ }
+
+ @Test
+ @LinuxOnly
+ public void testSSOReleaseOneAttribute() throws Exception {
+ super.testSSOReleaseOneAttribute();
+ }
+
+ @Test
+ @LinuxOnly
+ public void testSSODoNotRememberConsent() throws Exception {
+ super.testSSODoNotRememberConsent();
+ }
+
+ @Test
+ @LinuxOnly
+ public void testSSOGlobalConsent() throws Exception {
+ super.testSSOGlobalConsent();
+ }
+
+ @Test
+ @LinuxOnly
+ public void testSSOTermsOfUse() throws Exception {
+ super.testSSOTermsOfUse();
+ }
+}
diff --git a/src/test/resources/net/shibboleth/idp/integration/tests/postgres/create-table.sh b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/create-table.sh
new file mode 100644
index 0000000..8144735
--- /dev/null
+++ b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/create-table.sh
@@ -0,0 +1,8 @@
+CREATE TABLE StorageRecords (
+ context varchar(255) NOT NULL,
+ id varchar(255) NOT NULL,
+ expires bigint DEFAULT NULL,
+ value text NOT NULL,
+ version bigint NOT NULL,
+ PRIMARY KEY (context, id)
+);
\ No newline at end of file
diff --git a/src/test/resources/net/shibboleth/idp/integration/tests/postgres/docker-compose.yml b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/docker-compose.yml
new file mode 100644
index 0000000..77cfacf
--- /dev/null
+++ b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/docker-compose.yml
@@ -0,0 +1,15 @@
+services:
+
+ db:
+ image: postgres
+ restart: always
+ # set shared memory limit when using docker-compose
+ shm_size: 128mb
+ environment:
+ POSTGRES_USER: test
+ POSTGRES_PASSWORD: test
+ POSTGRES_DB: test
+ ports:
+ - 5432:5432
+ volumes:
+ - ./create-table.sql:/docker-entrypoint-initdb.d/create-table.sql
\ No newline at end of file
diff --git a/src/test/resources/net/shibboleth/idp/integration/tests/postgres/global.xml b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/global.xml
new file mode 100644
index 0000000..0bb3e75
--- /dev/null
+++ b/src/test/resources/net/shibboleth/idp/integration/tests/postgres/global.xml
@@ -0,0 +1,9 @@
+ <bean id="my.dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" lazy-init="true"
+ p:jdbcUrl="jdbc:postgresql://localhost:5432/test?loggerLevel=OFF"
+ p:username="test"
+ p:password="test" />
+
+ <bean id="my.JDBCStorageService" parent="shibboleth.JDBCStorageService"
+ p:dataSource-ref="my.dataSource"
+ p:transactionIsolation="4"
+ p:retryableErrors="40001"/>
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list