[java-plugin-shibd] branch main updated: Unit test for resource state mapping action.

Scott Cantor cantor.2 at osu.edu
Wed Aug 21 17:12:14 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=f815d364b299dd60a42d82ef51a24de3dfe36dd6

The following commit(s) were added to refs/heads/main by this push:
     new f815d36  Unit test for resource state mapping action.
f815d36 is described below

commit f815d364b299dd60a42d82ef51a24de3dfe36dd6
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Aug 21 13:12:11 2024 -0400

    Unit test for resource state mapping action.
---
 .../sp/profile/impl/MapResourceToStateToken.java   |  13 +-
 .../sp/profile/impl/BaseAgplicationActionTest.java |   7 +
 .../profile/impl/MapResourceToStateTokenTest.java  | 218 +++++++++++++++++++++
 .../shibboleth/sp/testing/MockAgentResolver.java   |   2 +-
 4 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/MapResourceToStateToken.java b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/MapResourceToStateToken.java
index 71948a2..e4f71da 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/MapResourceToStateToken.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/profile/impl/MapResourceToStateToken.java
@@ -18,6 +18,7 @@ import java.io.IOException;
 
 import javax.annotation.Nonnull;
 
+import org.opensaml.profile.action.EventIds;
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 
@@ -37,11 +38,21 @@ import net.shibboleth.sp.profile.InitiatorConstants;
 /**
  * Action that maps a requested resource URL into a state token to be consumed
  * by protocol request generation logic.
+ * 
+ * <p>The existence of a {@link InitiatorConstants#STATE} input parameter will cause
+ * the action to be skipped, as will the absence of a {@link RemotedHttpServletRequest#STRUCTURE_NAME}
+ * member with at least a {@link RemotedHttpServletRequest#REQUEST_URL} member.</p>
+ * 
+ * <p>Otherwise the raw bytes of the {@link RemotedHttpServletRequest#REQUEST_URL} and
+ * {@link RemotedHttpServletRequest#QUERY_STRING} members will be used to construct the
+ * resource URL to build a state token for.</p>
+ * 
+ * @event {@link EventIds#PROCEED_EVENT_ID}
  */
 public class MapResourceToStateToken extends AbstractApplicationAction {
 
     /** Static byte array with query string separator. */
-    @Nonnull @NotEmpty private static byte[] QUERY_SEPERATOR = {'?'};
+    @Nonnull @NotEmpty public static byte[] QUERY_SEPERATOR = {'?'};
     
     /** Class logger. */
     @Nonnull private Logger log = LoggerFactory.getLogger(MapResourceToStateToken.class);
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgplicationActionTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgplicationActionTest.java
index 3c0e860..d8cfdb7 100644
--- a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgplicationActionTest.java
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/BaseAgplicationActionTest.java
@@ -15,6 +15,7 @@
 package net.shibboleth.sp.profile.impl;
 
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.testing.MockReloadableService;
 import net.shibboleth.sp.impl.BasicApplication;
 
 /**
@@ -34,6 +35,12 @@ public abstract class BaseAgplicationActionTest extends BaseAgentRequestTest {
         
         application = new BasicApplication();
         application.setId("test");
+        
+        application.setMetadataResolver(new MockReloadableService<>(null));
+        application.setAttributeResolver(new MockReloadableService<>(null));
+        application.setAttributeFilter(new MockReloadableService<>(null));
+        application.setAttributeTranscoderRegistry(new MockReloadableService<>(null));
+        
         //application.initialize();
         
         arc.setApplication(application);
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/MapResourceToStateTokenTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/MapResourceToStateTokenTest.java
new file mode 100644
index 0000000..62d0861
--- /dev/null
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/profile/impl/MapResourceToStateTokenTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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.io.IOException;
+import java.time.Duration;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.storage.impl.MemoryStorageService;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+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.primitives.Bytes;
+
+import net.shibboleth.idp.profile.testing.ActionTestingSupport;
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.codec.Base64Support;
+import net.shibboleth.shared.codec.DecodingException;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.NonnullSupplier;
+import net.shibboleth.sp.ddf.DDF;
+import net.shibboleth.sp.impl.CookieStateTokenManager;
+import net.shibboleth.sp.impl.PassthroughStateTokenManager;
+import net.shibboleth.sp.impl.StorageServiceStateTokenManager;
+import net.shibboleth.sp.messaging.RemotedHttpServletRequest;
+import net.shibboleth.sp.profile.InitiatorConstants;
+
+/**
+ * Unit test for {@link MapResourceToStateToken} action.
+ */
+ at SuppressWarnings("javadoc")
+public class MapResourceToStateTokenTest extends BaseAgplicationActionTest {
+
+    /** Test request URL. */
+    @Nonnull @NotEmpty private final static String TEST_URL = "https://sp.example.org/cgi-bin/test.cgi";
+
+    /** Test query string. */
+    @Nonnull @NotEmpty private final static String TEST_QUERY = "foo=bar%20baz&frobnitz=zorkmid";
+
+    private MapResourceToStateToken action;
+        
+    /**
+     * Set up test.
+     * 
+     * @throws ComponentInitializationException
+     */
+    @BeforeMethod
+    public void setUp() throws ComponentInitializationException {
+        super.beforeMethod();
+        
+        action = new MapResourceToStateToken();
+        action.initialize();
+    }
+    
+    /**
+     * Tear down test.
+     */
+    @AfterMethod
+    public void tearDown() {
+        action.destroy();
+    }
+
+    @Test
+    public void testNoRequest() {
+        final DDF input = new DDF(null).structure();
+        arc.setInput(input);
+        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        Assert.assertNull(input.getmember(InitiatorConstants.STATE).string());
+    }
+
+    @Test
+    public void testStateExists() {
+        final DDF input = new DDF(null).structure();
+        input.addmember(InitiatorConstants.STATE).string("foo");
+        arc.setInput(input);
+        
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        Assert.assertEquals(input.getmember(InitiatorConstants.STATE).string(), "foo");
+    }
+
+    @Test
+    public void testPassthroughURL() throws ComponentInitializationException, DecodingException {
+        
+        final PassthroughStateTokenManager manager = new PassthroughStateTokenManager();
+        manager.setId("test");
+        manager.initialize();
+        
+        application.setStateTokenManager(manager);
+        application.initialize();
+        
+        final DDF input = new DDF(null).structure();
+        final DDF httpreq = input.addmember(RemotedHttpServletRequest.STRUCTURE_NAME);
+        httpreq.addmember(RemotedHttpServletRequest.REQUEST_URL).unsafe_string(TEST_URL.getBytes());
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        final String token = input.getmember(InitiatorConstants.STATE).string();
+        assert token != null;
+        
+        Assert.assertEquals(Base64Support.decodeURLSafe(token), TEST_URL.getBytes());
+    }
+
+    @Test
+    public void testPassthroughURLAndQuery() throws ComponentInitializationException, DecodingException {
+        
+        final PassthroughStateTokenManager manager = new PassthroughStateTokenManager();
+        manager.setId("test");
+        manager.initialize();
+        
+        application.setStateTokenManager(manager);
+        application.initialize();
+        
+        final DDF input = new DDF(null).structure();
+        final DDF httpreq = input.addmember(RemotedHttpServletRequest.STRUCTURE_NAME);
+        httpreq.addmember(RemotedHttpServletRequest.REQUEST_URL).unsafe_string(TEST_URL.getBytes());
+        httpreq.addmember(RemotedHttpServletRequest.QUERY_STRING).unsafe_string(TEST_QUERY.getBytes());
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        final String token = input.getmember(InitiatorConstants.STATE).string();
+        assert token != null;
+        
+        Assert.assertEquals(
+                Base64Support.decodeURLSafe(token),
+                Bytes.concat(TEST_URL.getBytes(), MapResourceToStateToken.QUERY_SEPERATOR, TEST_QUERY.getBytes()));
+    }
+
+    @Test
+    public void testStorageURL() throws ComponentInitializationException, DecodingException, IOException {
+        
+        final MemoryStorageService storage = new MemoryStorageService();
+        storage.setId("test");
+        storage.setCleanupInterval(Duration.ZERO);
+        storage.initialize();
+        
+        final StorageServiceStateTokenManager manager = new StorageServiceStateTokenManager();
+        manager.setId("test");
+        manager.setStorageService(storage);
+        manager.initialize();
+        
+        application.setStateTokenManager(manager);
+        application.initialize();
+        
+        final DDF input = new DDF(null).structure();
+        final DDF httpreq = input.addmember(RemotedHttpServletRequest.STRUCTURE_NAME);
+        httpreq.addmember(RemotedHttpServletRequest.REQUEST_URL).unsafe_string(TEST_URL.getBytes());
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        final String token = input.getmember(InitiatorConstants.STATE).string();
+        assert token != null;
+        
+        final byte[] value = manager.recoverFromStateToken(agent, application, token);
+        Assert.assertEquals(value, TEST_URL.getBytes());
+    }
+    
+    @Test
+    public void testCookieURL() throws ComponentInitializationException, DecodingException, IOException {
+        
+        final MockHttpServletRequest request = new MockHttpServletRequest();
+        final MockHttpServletResponse response = new MockHttpServletResponse();
+        
+        final CookieStateTokenManager manager = new CookieStateTokenManager();
+        manager.setId("test");
+        manager.setHttpServletRequestSupplier(NonnullSupplier.of(request));
+        manager.setHttpServletResponseSupplier(NonnullSupplier.of(response));
+        manager.initialize();
+        
+        application.setStateTokenManager(manager);
+        application.initialize();
+        
+        final DDF input = new DDF(null).structure();
+        final DDF httpreq = input.addmember(RemotedHttpServletRequest.STRUCTURE_NAME);
+        httpreq.addmember(RemotedHttpServletRequest.REQUEST_URL).unsafe_string(TEST_URL.getBytes());
+        arc.setInput(input);
+
+        final Event event = action.execute(src);
+        ActionTestingSupport.assertProceedEvent(event);
+        
+        final String token = input.getmember(InitiatorConstants.STATE).string();
+        assert token != null;
+        
+        request.setCookies(response.getCookies());
+        
+        final byte[] value = manager.recoverFromStateToken(agent, application, token);
+        Assert.assertEquals(value, TEST_URL.getBytes());
+    }
+
+}
\ No newline at end of file
diff --git a/sp-testing/src/main/java/net/shibboleth/sp/testing/MockAgentResolver.java b/sp-testing/src/main/java/net/shibboleth/sp/testing/MockAgentResolver.java
index 1a1a792..be29969 100644
--- a/sp-testing/src/main/java/net/shibboleth/sp/testing/MockAgentResolver.java
+++ b/sp-testing/src/main/java/net/shibboleth/sp/testing/MockAgentResolver.java
@@ -33,7 +33,7 @@ import net.shibboleth.sp.AgentResolver;
 public class MockAgentResolver extends MockResolver<Agent> implements AgentResolver {
 
     /** Agent to return. */
-    private final Agent agent;
+    @Nonnull private final Agent agent;
     
     /**
      * Constructor.

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list