[java-opensaml] 09/11: Add a new general purpose configurable SAML entityID lookup function.

Brent Putman putmanb at georgetown.edu
Thu Jan 30 02:17:34 EST 2020


This is an automated email from the git hooks/post-receive script.

putmanb pushed a commit to branch master
in repository java-opensaml.

View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=fcefeca9df355bea847a118d5051eded0c3f070e

commit fcefeca9df355bea847a118d5051eded0c3f070e
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Thu Jan 30 01:49:52 2020 -0500

    Add a new general purpose configurable SAML entityID lookup function.
---
 .../impl/MessageContextEntityIDLookup.java         | 139 +++++++++++++++++++++
 .../impl/MessageContextEntityIDLookupTest.java     |  91 ++++++++++++++
 2 files changed, 230 insertions(+)

diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookup.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookup.java
new file mode 100644
index 0000000..91d7516
--- /dev/null
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookup.java
@@ -0,0 +1,139 @@
+/*
+ * 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 org.opensaml.saml.common.binding.security.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.InOutOperationContext;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.messaging.context.navigate.ContextDataLookupFunction;
+import org.opensaml.messaging.context.navigate.RecursiveTypedParentContextLookup;
+import org.opensaml.saml.common.messaging.context.AbstractSAMLEntityContext;
+import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * A general purpose context data lookup function for resolving a SAML entity ID relative to a
+ * starting input {@link MessageContext}, configurable for either the inbound or outbound direction,
+ * and also to specify the concrete type of {@link AbstractSAMLEntityContext} child context to resolve.
+ */
+public class MessageContextEntityIDLookup implements ContextDataLookupFunction<MessageContext, String> {
+    
+    /** Used to indicate the target message context. */
+    public enum Direction {
+        /** Indicates to use the inbound message context, obtained via 
+         * {@link InOutOperationContext#getInboundMessageContext()}. */
+        INBOUND, 
+        
+        /** Indicates to use the outbound message context, obtained via
+         * {@link InOutOperationContext#getOutboundMessageContext()}. */
+        OUTBOUND,
+        };
+        
+    /** The message context to evaluate as the entityContext parent. */    
+    @Nonnull private Direction direction;
+        
+    /** The actual context class holding the authenticatable SAML entity. */
+    @Nonnull private Class<? extends AbstractSAMLEntityContext> entityContextClass;
+    
+    /** Parent operation context lookup function. */
+    @Nonnull private Function<MessageContext,MessageContext> parentLookup;
+    
+    /**
+     * Constructor.
+     * 
+     * <p>
+     * This constructor defaults to {@link SAMLPeerEntityContext} as the entity context class.
+     * </p>
+     */
+    public MessageContextEntityIDLookup() {
+        this(SAMLPeerEntityContext.class);
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param clazz the entity context class.
+     */
+    public MessageContextEntityIDLookup(
+            @Nonnull final Class<? extends AbstractSAMLEntityContext> clazz) {
+        entityContextClass = Constraint.isNotNull(clazz, "The SAML Entity context class may not be null;");
+        parentLookup = new MessageContextLookup()
+                .compose(new RecursiveTypedParentContextLookup<>(InOutOperationContext.class));
+    }
+    
+    /**
+     * Set the direction of operation.
+     * 
+     * @param dir the direction of operation
+     */
+    public void setDirection(@Nonnull final Direction dir) {
+        direction = Constraint.isNotNull(dir, "Direction was null");
+    }
+
+    /** {@inheritDoc} */
+    public String apply(@Nullable final MessageContext messageContext) {
+        if (messageContext == null) {
+            return null;
+        }
+
+        final MessageContext msgContext = parentLookup.apply(messageContext);
+        if (msgContext == null) {
+            return null;
+        }
+
+        final AbstractSAMLEntityContext entityContext = msgContext.getSubcontext(entityContextClass);
+        if (entityContext == null) {
+            return null;
+        }
+
+        return entityContext.getEntityId();
+    }
+    
+    /**
+     * Class for picking either the inbound or outbound message context, depending on configuration.
+     */
+    private class MessageContextLookup implements ContextDataLookupFunction<InOutOperationContext, MessageContext> {
+
+        /** {@inheritDoc} */
+        public MessageContext apply(@Nullable final InOutOperationContext opContext) {
+            if (opContext == null) {
+                return null;
+            }
+            
+            if (direction == null) {
+                throw new IllegalArgumentException("Direction must be supplied");
+            }
+            
+            switch(direction) {
+                case INBOUND:
+                    return opContext.getInboundMessageContext();
+                case OUTBOUND:
+                    return opContext.getOutboundMessageContext();
+                default:
+                    throw new IllegalArgumentException("Saw unsupported value: " + direction);
+            }
+        }
+        
+    }
+        
+}
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookupTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookupTest.java
new file mode 100644
index 0000000..6f00ec5
--- /dev/null
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/MessageContextEntityIDLookupTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 org.opensaml.saml.common.binding.security.impl;
+
+import org.opensaml.messaging.context.InOutOperationContext;
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.saml.common.binding.security.impl.MessageContextEntityIDLookup.Direction;
+import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
+import org.opensaml.saml.common.messaging.context.SAMLSelfEntityContext;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import junit.framework.Assert;
+
+/**
+ *
+ */
+public class MessageContextEntityIDLookupTest {
+    
+    private InOutOperationContext opContext;
+    
+    @BeforeMethod
+    public void setUp() {
+        opContext = new InOutOperationContext(new MessageContext(), new MessageContext());
+        opContext.getInboundMessageContext().getSubcontext(SAMLPeerEntityContext.class, true).setEntityId("inbound-peer");
+        opContext.getInboundMessageContext().getSubcontext(SAMLSelfEntityContext.class, true).setEntityId("inbound-self");
+        opContext.getOutboundMessageContext().getSubcontext(SAMLPeerEntityContext.class, true).setEntityId("outbound-peer");
+        opContext.getOutboundMessageContext().getSubcontext(SAMLSelfEntityContext.class, true).setEntityId("outbound-self");
+    }
+    
+    @Test
+    public void testInboundPeer() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLPeerEntityContext.class);
+        lookup.setDirection(Direction.INBOUND);
+        Assert.assertEquals("inbound-peer", lookup.apply(opContext.getInboundMessageContext()));
+        Assert.assertEquals("inbound-peer", lookup.apply(opContext.getOutboundMessageContext()));
+    }
+    
+    @Test
+    public void testInboundSelf() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLSelfEntityContext.class);
+        lookup.setDirection(Direction.INBOUND);
+        Assert.assertEquals("inbound-self", lookup.apply(opContext.getInboundMessageContext()));
+        Assert.assertEquals("inbound-self", lookup.apply(opContext.getOutboundMessageContext()));
+    }
+    
+    @Test
+    public void testOutboundPeer() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLPeerEntityContext.class);
+        lookup.setDirection(Direction.OUTBOUND);
+        Assert.assertEquals("outbound-peer", lookup.apply(opContext.getInboundMessageContext()));
+        Assert.assertEquals("outbound-peer", lookup.apply(opContext.getOutboundMessageContext()));
+    }
+    
+    @Test
+    public void testOutboundSelf() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLSelfEntityContext.class);
+        lookup.setDirection(Direction.OUTBOUND);
+        Assert.assertEquals("outbound-self", lookup.apply(opContext.getInboundMessageContext()));
+        Assert.assertEquals("outbound-self", lookup.apply(opContext.getOutboundMessageContext()));
+    }
+    
+    @Test
+    public void testNoParentOpContext() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLPeerEntityContext.class);
+        Assert.assertNull(lookup.apply(new MessageContext()));
+    }
+    
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void testNoDirection() {
+        MessageContextEntityIDLookup lookup  = new MessageContextEntityIDLookup(SAMLPeerEntityContext.class);
+        Assert.assertEquals("outbound-peer", lookup.apply(opContext.getInboundMessageContext()));
+    }
+    
+
+}

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


More information about the commits mailing list