[java-plugin-shibd] branch main updated: Tests for discovery request action.

Scott Cantor cantor.2 at osu.edu
Tue Jul 1 12:40:33 UTC 2025


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=44d888a90d1e62a4947fff15ceccc2a4c3b6d9b0

The following commit(s) were added to refs/heads/main by this push:
     new 44d888a  Tests for discovery request action.
44d888a is described below

commit 44d888a90d1e62a4947fff15ceccc2a4c3b6d9b0
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 1 08:40:28 2025 -0400

    Tests for discovery request action.
---
 .../idp/flows/sp/initiator/disco/disco-beans.xml   |   1 +
 .../shibboleth/sp/profile/AbstractAgentAction.java |   5 +
 .../sp/profile/impl/IssueDiscoveryRequest.java     |   7 +-
 .../sp/profile/impl/IssueDiscoveryRequestTest.java | 178 +++++++++++++++++++++
 4 files changed, 189 insertions(+), 2 deletions(-)

diff --git a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml
index 9a68c38..d0c3754 100644
--- a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml
+++ b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/initiator/disco/disco-beans.xml
@@ -19,6 +19,7 @@
         
     <bean id="IssueDiscoveryRequest"
         class="net.shibboleth.sp.profile.impl.IssueDiscoveryRequest" scope="prototype"
+        p:createOutputObjects="true"
         p:httpServletResponseSupplier-ref="shibboleth.RemotedHttpServletResponseSupplier" />
 
 
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/profile/AbstractAgentAction.java b/sp-server-api/src/main/java/net/shibboleth/sp/profile/AbstractAgentAction.java
index 79edcba..e810ea8 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/profile/AbstractAgentAction.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/profile/AbstractAgentAction.java
@@ -51,6 +51,11 @@ public abstract class AbstractAgentAction extends AbstractAgentRequestAction {
     /** Whether to create the output objects into which the message will be encoded. */
     private boolean createOutputObjects;
     
+    /**
+     * Gets whether to create an output {@link DDF} and {@link RemotedHttpServletResponse}.
+     *
+     * @return whether to create output objects
+     */
     public boolean isCreateOutputObjects() {
         return createOutputObjects;
     }
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java
index 629d3c6..9bbaf17 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequest.java
@@ -35,6 +35,7 @@ import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 import net.shibboleth.sp.ddf.DDF;
 import net.shibboleth.sp.messaging.RemotedHttpServletRequestResponseContext;
@@ -189,6 +190,8 @@ public class IssueDiscoveryRequest extends AbstractApplicationAction {
             discoveryURL += "&isPassive=1";
         }
         
+        ensureOutputObjects();
+        
         // Issue a redirect while the remoted layer is loaded in.
         try {
             RemotedHttpServletRequestResponseContext.loadCurrent(null,
@@ -211,7 +214,7 @@ public class IssueDiscoveryRequest extends AbstractApplicationAction {
         @Nullable public String apply(@Nullable final ProfileRequestContext input) {
             
             try {
-                final RelyingPartyConfiguration rpConfig = ensureApplication().resolveSingle(null);
+                final RelyingPartyConfiguration rpConfig = ensureApplication().resolveSingle(new CriteriaSet());
                 if (rpConfig != null) {
                     return rpConfig.getIssuer(input);
                 }
@@ -230,7 +233,7 @@ public class IssueDiscoveryRequest extends AbstractApplicationAction {
 
         /** {@inheritDoc} */
         public boolean test(@Nullable final ProfileRequestContext t) {
-            return input.getmember("isPassive").integer() == 1
+            return Integer.valueOf(1).equals(input.getmember("isPassive").integer())
                     && "none".equals(input.getmember("prompt").string());
         }
     }
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequestTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequestTest.java
new file mode 100644
index 0000000..c6ccb6e
--- /dev/null
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/IssueDiscoveryRequestTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.profile.impl;
+
+import java.nio.charset.StandardCharsets;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.profile.action.EventIds;
+import org.springframework.webflow.execution.Event;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.escape.Escaper;
+import com.google.common.net.UrlEscapers;
+
+import net.shibboleth.idp.profile.testing.ActionTestingSupport;
+import net.shibboleth.profile.relyingparty.BasicRelyingPartyConfiguration;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.messaging.RemotedHttpServletResponse;
+import net.shibboleth.sp.messaging.impl.RemotedlHttpServletResponseSupplier;
+import net.shibboleth.sp.profile.InitiatorConstants;
+
+/**
+ * Unit test for {@link IssueDiscoveryRequest} action.
+ */
+ at SuppressWarnings("javadoc")
+public class IssueDiscoveryRequestTest extends BaseAgplicationActionTest {
+
+    /** Test discovery URL. */
+    @Nonnull @NotEmpty private final static String TEST_DISCOVERY_URL = "https://ds.example.org/DS";
+
+    /** Test issuer. */
+    @Nonnull @NotEmpty private final static String TEST_ISSUER = "https://sp.example.org/sp";
+
+    /** Test issuer. */
+    @Nonnull @NotEmpty private final static String TEST_RESPONSE_URL = "https://sp.example.org/handler?DS=1";
+
+    final Escaper escaper = UrlEscapers.urlFormParameterEscaper();
+    
+    private String issuer;
+    private String discoveryURL;
+    private IssueDiscoveryRequest action;
+
+    /**
+     * Set up test.
+     * 
+     * @throws ComponentInitializationException
+     */
+    @BeforeMethod
+    public void setUp() throws ComponentInitializationException {
+        super.beforeMethod();
+        
+        BasicRelyingPartyConfiguration rpc = new BasicRelyingPartyConfiguration();
+        rpc.setId("default");
+        rpc.setIssuerLookupStrategy(input -> issuer);
+        rpc.initialize();
+        
+        application.setUnverifiedConfiguration(rpc);
+        application.initialize();
+        
+        action = new IssueDiscoveryRequest();
+        action.setCreateOutputObjects(true);
+        action.setDiscoveryURLLookupStrategy(input -> discoveryURL);
+        action.setHttpServletResponseSupplier(new RemotedlHttpServletResponseSupplier());
+        action.initialize();
+        
+        discoveryURL = TEST_DISCOVERY_URL;
+        issuer = TEST_ISSUER;
+    }
+    
+    /**
+     * Tear down test.
+     */
+    @AfterMethod
+    public void tearDown() {
+        action.destroy();
+        action = null;
+    }
+
+    @Test
+    public void testNoURL() throws ComponentInitializationException {
+        discoveryURL = null;
+        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_PROC_ERROR);
+        final DDF output = arc.getOutput();
+        Assert.assertNull(output);
+    }
+
+    @Test
+    public void testNoIssuer() throws ComponentInitializationException {
+        issuer = null;
+        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertEvent(event, EventIds.MESSAGE_PROC_ERROR);
+        final DDF output = arc.getOutput();
+        Assert.assertNull(output);
+    }
+    
+    @Test
+    public void testNoInput() throws ComponentInitializationException {        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
+        final DDF output = arc.getOutput();
+        Assert.assertNull(output);
+    }
+    
+    @Test
+    public void testNoReturnURL() throws ComponentInitializationException {
+        final DDF input = new DDF(null).structure();
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertEvent(event, EventIds.INVALID_MESSAGE);
+        final DDF output = arc.getOutput();
+        Assert.assertNull(output);
+    }
+    
+    @Test
+    public void testNoState() throws ComponentInitializationException {
+        final DDF input = new DDF(null).structure();
+        input.addmember(InitiatorConstants.DISCOVERY_RETURN_URL).string(escaper.escape("https://sp.example.org/handler?DS=1"));
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        final DDF output = arc.getOutput();
+        assert output != null;
+        final byte[] redirect = output.getmember(
+                RemotedHttpServletResponse.STRUCTURE_NAME + '.' +
+                    RemotedHttpServletResponse.REDIRECT).unsafe_string();
+        Assert.assertEquals(redirect, buildDiscoveryURL(TEST_DISCOVERY_URL, TEST_RESPONSE_URL, null));
+    }
+    
+    /**
+     * Builds final URL to test for.
+     * 
+     * @param url the base discovery location
+     * @param returnURL the return parameter as fed by an agent
+     * @param state the state token if any
+     * 
+     * @return the final URL
+     */
+    @Nonnull private byte[] buildDiscoveryURL(@Nonnull final String url, @Nonnull final String returnURL,
+            @Nullable final String state) {
+        final StringBuilder builder = new StringBuilder(url);
+        
+        builder.append("?return=");
+        if (state != null) {
+            builder.append(escaper.escape(returnURL) + escaper.escape("&state=" + state));
+        } else {
+            builder.append(escaper.escape(returnURL));
+        }
+        builder.append("&entityID=").append(escaper.escape(TEST_ISSUER));
+        
+        return builder.toString().getBytes(StandardCharsets.UTF_8);
+    }
+        
+}
\ 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