[java-plugin-shibd] 02/02: Getting flow testing framework in place.
Scott Cantor
cantor.2 at osu.edu
Tue Jul 2 16:53:23 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd.git;a=commit;h=82fcbdb9053341e8ee30b62a876528c17e2b1206
commit 82fcbdb9053341e8ee30b62a876528c17e2b1206
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 2 12:53:18 2024 -0400
Getting flow testing framework in place.
---
sp-conf-impl/pom.xml | 88 ++++++++++++
.../shibboleth/sp/flows/AbstractSPFlowTest.java | 159 +++++++++++++++++++++
.../java/net/shibboleth/sp/flows/PingFlowTest.java | 49 +++++++
.../java/net/shibboleth/sp/flows/package-info.java | 18 +++
.../net/shibboleth/idp/module/conf/global.xml | 72 ++++++++++
5 files changed, 386 insertions(+)
diff --git a/sp-conf-impl/pom.xml b/sp-conf-impl/pom.xml
index 05a27ad..0c8c06e 100644
--- a/sp-conf-impl/pom.xml
+++ b/sp-conf-impl/pom.xml
@@ -20,6 +20,12 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>sp-server-api</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sp-server-impl</artifactId>
@@ -108,6 +114,11 @@
<artifactId>shib-networking-spring</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-security-spring</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>${shib-shared.groupId}</groupId>
<artifactId>shib-spring</artifactId>
@@ -118,6 +129,12 @@
<artifactId>shib-velocity-spring</artifactId>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -137,6 +154,77 @@
</dependency>
<!-- Test Dependencies -->
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-conf-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-conf-impl</artifactId>
+ <version>${idp.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${idp.groupId}</groupId>
+ <artifactId>idp-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${shib-shared.groupId}</groupId>
+ <artifactId>shib-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${spring-webflow.groupId}</groupId>
+ <artifactId>spring-webflow</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring-webflow.groupId}</groupId>
+ <artifactId>spring-binding</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-beans</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-context</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-expression</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-web</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${spring.groupId}</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.janino</groupId>
+ <artifactId>janino</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java
new file mode 100644
index 0000000..28b5a00
--- /dev/null
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/AbstractSPFlowTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+package net.shibboleth.sp.flows;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.codec.binary.Base64;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.storage.StorageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.springframework.webflow.test.MockExternalContext;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+
+import net.shibboleth.idp.test.flows.AbstractFlowTest;
+import net.shibboleth.shared.security.DataSealer;
+import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
+import net.shibboleth.sp.context.AgentRequestContext;
+import net.shibboleth.sp.ddf.DDF;
+
+/**
+ * Abstract unit test class for SP flows.
+ */
+ at ContextConfiguration(locations = { "classpath*:/META-INF/net.shibboleth.idp/postconfig.xml",})
+ at SuppressWarnings("null")
+public abstract class AbstractSPFlowTest extends AbstractFlowTest {
+
+ /** End state ID. */
+ @Nonnull public static final String END_STATE_ID = "end";
+
+ /** Event member of output.. */
+ @Nonnull public static final String EVENT_MEMBER_NAME = "event";
+
+ protected String flowId;
+
+ protected String endStateId;
+
+ @Autowired
+ @Qualifier("shibboleth.DataSealer")
+ private DataSealer dataSealer;
+
+ @Autowired
+ @Qualifier("shibboleth.StorageService")
+ StorageService storageService;
+
+ protected AbstractSPFlowTest(final String id) {
+ this(id, END_STATE_ID);
+ }
+
+ protected AbstractSPFlowTest(final String id, final String endId) {
+ flowId = id;
+ endStateId = endId == null ? END_STATE_ID : endId;
+ }
+
+ /**
+ * Initialize mock request, response, and external context. Overrides to remove authorization header.
+ */
+ @Override
+ @BeforeMethod public void initializeMocks() {
+ overrideEndStateOutput(flowId, endStateId);
+
+ request = new MockHttpServletRequest();
+ response = new MockHttpServletResponse();
+ externalContext = new MockExternalContext();
+ externalContext.setNativeRequest(request);
+ externalContext.setNativeResponse(response);
+ }
+
+ /**
+ * Load the mock request/response objects.
+ */
+ @Override
+ @BeforeMethod public void initializeThreadLocals() {
+ HttpServletRequestResponseContext.loadCurrent(request, response);
+ }
+
+ @Nonnull protected DataSealer getDataSealer() {
+ assert dataSealer != null;
+ return dataSealer;
+ }
+
+ protected void setJsonRequest(final String method, final String body) {
+ setRequest(method, body, "application/json");
+ }
+
+ protected void setHttpFormRequest(final String method, final Map<String, String> parameters) {
+ setHttpFormRequest(request, method, parameters);
+ }
+
+ protected static void setHttpFormRequest(final MockHttpServletRequest request, final String method, final Map<String, String> parameters) {
+ setRequest(request, method, "", "application/x-www-form-urlencoded");
+ request.setParameters(parameters);
+ }
+
+ protected void setBasicAuth(final String username, final String password) {
+ request.removeHeader("Authorization");
+ request.addHeader("Authorization",
+ "Basic " + new String(Base64.encodeBase64(new String(username + ":" + password).getBytes())));
+ }
+
+ protected void setRequest(final String method, final String body, final String contentType) {
+ setRequest(request, method, body, contentType);
+ }
+
+ protected static void setRequest(final MockHttpServletRequest request, final String method, final String body, final String contentType) {
+ request.setMethod(method);
+ request.setContentType(contentType);
+ request.setContent(body.getBytes());
+ }
+
+ /**
+ * Checks that an output {@link DDF} was prepared, packaged in the response, and contains an event
+ * that matches the specified value.
+ *
+ * @param result flow result
+ * @param eventId value to check for
+ *
+ * @throws IOException on error
+ */
+ protected void assertOutputMessageEvent(@Nonnull final FlowExecutionResult result, @Nonnull final String eventId)
+ throws IOException {
+ final ProfileRequestContext prc = retrieveProfileRequestContext(result);
+ final AgentRequestContext arc = prc.ensureSubcontext(AgentRequestContext.class);
+ final DDF output = arc.getOutput();
+ assert output != null;
+ Assert.assertTrue(output.isstruct());
+ Assert.assertEquals(output.getmember(EVENT_MEMBER_NAME).string(), eventId);
+
+ Assert.assertEquals(response.getContentType(), "text/plain");
+ try (final InputStream in = new ByteArrayInputStream(response.getContentAsByteArray())) {
+ final DDF body = DDF.deserialize(in);
+ Assert.assertTrue(body.isstruct());
+ Assert.assertEquals(body.getmember(EVENT_MEMBER_NAME).string(), eventId);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java
new file mode 100644
index 0000000..6d9d603
--- /dev/null
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/PingFlowTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package net.shibboleth.sp.flows;
+
+import java.io.IOException;
+
+import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.authn.AuthnEventIds;
+
+/**
+ * Unit test for the OP discovery flow.
+ */
+public class PingFlowTest extends AbstractSPFlowTest {
+
+ /** Flow ID. */
+ public static final String FLOW_ID = "sp/ping";
+
+ protected PingFlowTest() {
+ super(FLOW_ID);
+ }
+
+ /**
+ * Ping flow test.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testUnauhenticated() throws IOException {
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertFlowExecutionResult(result, FLOW_ID);
+ assertFlowExecutionOutcome(result.getOutcome());
+ assertOutputMessageEvent(result, AuthnEventIds.NO_CREDENTIALS);
+ }
+
+}
\ No newline at end of file
diff --git a/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/package-info.java b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/package-info.java
new file mode 100644
index 0000000..ea8b2ad
--- /dev/null
+++ b/sp-conf-impl/src/test/java/net/shibboleth/sp/flows/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+/**
+ * Unit tests for SP flows.
+ */
+package net.shibboleth.sp.flows;
\ No newline at end of file
diff --git a/sp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml b/sp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
new file mode 100644
index 0000000..cfe3329
--- /dev/null
+++ b/sp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- Use this file to define any custom beans needed globally. -->
+
+ <!--
+ Algorithm include/exclude sets that override or merge with library defaults. Normally you can leave these
+ empty or commented and use the system defaults, but you can override those defaults using these beans.
+ Each <value> element is an algorithm URI; you can also use <util:constant> elements in place of literal values.
+ -->
+
+ <!--
+ <util:set id="shibboleth.IncludedSignatureAlgorithms">
+ </util:set>
+
+ <util:set id="shibboleth.ExcludedSignatureAlgorithms">
+ </util:set>
+
+ <util:set id="shibboleth.IncludedEncryptionAlgorithms">
+ </util:set>
+
+ <util:set id="shibboleth.ExcludedEncryptionAlgorithms">
+ </util:set>
+ -->
+
+ <!--
+ If you need to define and inject custom Java object(s) into the various views used throughout the
+ system (errors, login, logout, etc.), you can uncomment and define the bean below to be of any
+ type required. It will appear in the view scope as a variable named "custom".
+
+ The example below defines the bean as a map, which allows you to inject multiple objects under
+ named keys to expand the feature to support multiple injected objects.
+ -->
+
+ <!--
+ <util:map id="shibboleth.CustomViewContext">
+ <entry key="foo" value="bar"/>
+ </util:map>
+ -->
+
+ <util:set id="testbed.MetadataIndexes">
+ <bean class="org.opensaml.saml.metadata.resolver.index.impl.SAMLArtifactMetadataIndex" />
+ <ref bean="shibboleth.CASMetadataIndices" />
+ </util:set>
+
+ <bean id="exampleMetadata" class="org.springframework.core.io.ClassPathResource">
+ <constructor-arg value="/metadata/example-metadata.xml"/>
+ </bean>
+
+ <bean id="exampleMetadata-sp123" class="org.springframework.core.io.ClassPathResource">
+ <constructor-arg value="/metadata/example-sp123-metadata.xml"/>
+ </bean>
+
+ <util:list id="testbed.MetadataResolverResources">
+ <value>%{idp.home}/conf/metadata-providers.xml</value>
+ <value>%{idp.home}/conf/metadata-filters.xml</value>
+ </util:list>
+
+</beans>
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list