[java-identity-provider] branch master updated: IDP-1624 - Preventing exporting DataConnectors from running during c14n

Scott Cantor cantor.2 at osu.edu
Tue Jun 23 18:41:14 UTC 2020


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

scantor pushed a commit to branch master
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=82417267e8112a56df4d470bb601b3543562dab5

The following commit(s) were added to refs/heads/master by this push:
       new  82417267e IDP-1624 - Preventing exporting DataConnectors from running during c14n
82417267e is described below

commit 82417267e8112a56df4d470bb601b3543562dab5
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jun 23 14:41:04 2020 -0400

    IDP-1624 - Preventing exporting DataConnectors from running during c14n
    
    https://issues.shibboleth.net/jira/browse/IDP-1624
    
    Add resolutionPhases attribute to resolution plugin schema.
---
 .../navigate/ResolutionLabelLookupFunction.java    | 41 +++++++++++
 .../resolver/logic/ResolutionLabelPredicate.java   | 60 ++++++++++++++++
 .../resolver/spring/BaseResolverPluginParser.java  | 45 +++++++++---
 .../spring/ad/SimpleAttributeParserTest.java       | 83 ++++++++++++++++++++--
 .../spring/ad/resolver/phasesAndParties.xml        |  9 +++
 .../spring/ad/resolver/resolutionPhases.xml        |  8 +++
 .../schema/shibboleth-attribute-resolver.xsd       | 18 +++--
 7 files changed, 243 insertions(+), 21 deletions(-)

diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/context/navigate/ResolutionLabelLookupFunction.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/context/navigate/ResolutionLabelLookupFunction.java
new file mode 100644
index 000000000..c7e7c3175
--- /dev/null
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/context/navigate/ResolutionLabelLookupFunction.java
@@ -0,0 +1,41 @@
+/*
+ * 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.attribute.resolver.context.navigate;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+
+/**
+ * A function that returns {@link AttributeResolutionContext#getResolutionLabel()} if available from a
+ * {@link AttributeResolutionContext} obtained via a lookup function defined on the base class.
+ * 
+ * <p>If a specific setting is unavailable, a null value is returned.</p>
+ * 
+ * @since 4.1.0
+ */
+public class ResolutionLabelLookupFunction extends AbstractAttributeResolutionLookupFunction<String> {
+
+    /** {@inheritDoc} */
+    @Override
+    @Nullable protected String doApply(@Nonnull final AttributeResolutionContext input) {
+        return input.getResolutionLabel();
+    }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/logic/ResolutionLabelPredicate.java b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/logic/ResolutionLabelPredicate.java
new file mode 100644
index 000000000..dc4830d13
--- /dev/null
+++ b/idp-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/logic/ResolutionLabelPredicate.java
@@ -0,0 +1,60 @@
+/*
+ * 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.attribute.resolver.logic;
+
+import java.util.Collection;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.idp.attribute.resolver.context.navigate.ResolutionLabelLookupFunction;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.logic.StrategyIndirectedPredicate;
+import net.shibboleth.utilities.java.support.primitive.StringSupport;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+/**
+ * Predicate that evaluates a {@link ProfileRequestContext} by looking for an attribute resolution label
+ * that matches one of a designated set or a generic predicate. The ID is obtained from a lookup
+ * function, by default from a {@link net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext}
+ * child of the profile request context.
+ * 
+ * @since 4.1.0
+ */
+public class ResolutionLabelPredicate extends StrategyIndirectedPredicate<ProfileRequestContext,String> {
+
+    /**
+     * Constructor.
+     * 
+     * @param candidates hardwired set of values to check against
+     */
+    public ResolutionLabelPredicate(@Nonnull @NonnullElements final Collection<String> candidates) {
+        super(new ResolutionLabelLookupFunction(), StringSupport.normalizeStringCollection(candidates));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param pred generalized predicate
+     */
+    public ResolutionLabelPredicate(@Nonnull final Predicate<String> pred) {
+        super(new ResolutionLabelLookupFunction(), pred);
+    }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/BaseResolverPluginParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/BaseResolverPluginParser.java
index 272472778..92f2c2f1e 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/BaseResolverPluginParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/BaseResolverPluginParser.java
@@ -22,10 +22,12 @@ import java.util.List;
 import javax.annotation.Nonnull;
 
 import net.shibboleth.ext.spring.util.SpringSupport;
+import net.shibboleth.idp.attribute.resolver.logic.ResolutionLabelPredicate;
 import net.shibboleth.idp.attribute.resolver.spring.impl.InputAttributeDefinitionParser;
 import net.shibboleth.idp.attribute.resolver.spring.impl.InputDataConnectorParser;
 import net.shibboleth.idp.profile.logic.RelyingPartyIdPredicate;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.logic.PredicateSupport;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 import net.shibboleth.utilities.java.support.xml.ElementSupport;
 
@@ -55,7 +57,7 @@ public abstract class BaseResolverPluginParser extends AbstractSingleBeanDefinit
         return defnId;
     }
 
-// Checkstyle: CyclomaticComplexity OFF
+// Checkstyle: CyclomaticComplexity|MethodLength OFF
     /** {@inheritDoc} */
     @Override protected void doParse(@Nonnull final Element config, @Nonnull final ParserContext parserContext,
             @Nonnull final BeanDefinitionBuilder builder) {
@@ -70,18 +72,39 @@ public abstract class BaseResolverPluginParser extends AbstractSingleBeanDefinit
         builder.setDestroyMethodName("destroy");
 
         if (config.hasAttributeNS(null, "activationConditionRef")) {
-            if (config.hasAttributeNS(null, "relyingParties")) {
-                log.warn("relyingParties ignored, using activationConditionRef");
+            if (config.hasAttributeNS(null, "relyingParties") || config.hasAttributeNS(null, "resolutionPhases")) {
+                log.warn("relyingParties/resolutionPhases ignored, using activationConditionRef");
             }
             builder.addPropertyReference("activationCondition",
                     StringSupport.trimOrNull(config.getAttributeNS(null, "activationConditionRef")));
-        } else if (config.hasAttributeNS(null, "relyingParties")) {
-            final BeanDefinitionBuilder rpBuilder =
-                    BeanDefinitionBuilder.genericBeanDefinition(RelyingPartyIdPredicate.class);
-            rpBuilder.setFactoryMethod("fromCandidates");
-            rpBuilder.addConstructorArgValue(
-                    SpringSupport.getAttributeValueAsList(config.getAttributeNodeNS(null, "relyingParties")));
-            builder.addPropertyValue("activationCondition", rpBuilder.getBeanDefinition());
+        } else {
+            BeanDefinitionBuilder rpBuilder = null;
+            BeanDefinitionBuilder phasesBuilder = null;
+            if (config.hasAttributeNS(null, "relyingParties")) {
+                rpBuilder = BeanDefinitionBuilder.genericBeanDefinition(RelyingPartyIdPredicate.class);
+                rpBuilder.setFactoryMethod("fromCandidates");
+                rpBuilder.addConstructorArgValue(
+                        SpringSupport.getAttributeValueAsList(config.getAttributeNodeNS(null, "relyingParties")));
+            }
+            
+            if (config.hasAttributeNS(null, "resolutionPhases")) {
+                phasesBuilder = BeanDefinitionBuilder.genericBeanDefinition(ResolutionLabelPredicate.class);
+                phasesBuilder.addConstructorArgValue(
+                        SpringSupport.getAttributeValueAsList(config.getAttributeNodeNS(null, "resolutionPhases")));
+            }
+
+            if (rpBuilder != null && phasesBuilder != null) {
+                final BeanDefinitionBuilder andBuilder =
+                        BeanDefinitionBuilder.genericBeanDefinition(PredicateSupport.class);
+                andBuilder.setFactoryMethod("and");
+                andBuilder.addConstructorArgValue(rpBuilder.getBeanDefinition());
+                andBuilder.addConstructorArgValue(phasesBuilder.getBeanDefinition());
+                builder.addPropertyValue("activationCondition", andBuilder.getBeanDefinition());
+            } else if (rpBuilder != null) {
+                builder.addPropertyValue("activationCondition", rpBuilder.getBeanDefinition());
+            } else if (phasesBuilder != null) {
+                builder.addPropertyValue("activationCondition", phasesBuilder.getBeanDefinition());
+            }
         }
 
         if (config.hasAttributeNS(null, "profileContextStrategyRef")) {
@@ -113,7 +136,7 @@ public abstract class BaseResolverPluginParser extends AbstractSingleBeanDefinit
         builder.addPropertyValue("dataConnectorDependencies", 
                 SpringSupport.parseCustomElements(dataConnectorDependencyElements, parserContext, builder));
     }
-// Checkstyle: CyclomaticComplexity ON
+// Checkstyle: CyclomaticComplexity|MethodLength ON
     
     /** Controls parsing of Dependencies. 
      * 
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
index 6259eb6a0..897a40bae 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/ad/SimpleAttributeParserTest.java
@@ -21,6 +21,7 @@ import static org.testng.Assert.*;
 
 import java.util.Collection;
 import java.util.Set;
+import java.util.function.Predicate;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.springframework.context.support.GenericApplicationContext;
@@ -35,6 +36,8 @@ import net.shibboleth.idp.attribute.resolver.AttributeDefinition;
 import net.shibboleth.idp.attribute.resolver.ResolverAttributeDefinitionDependency;
 import net.shibboleth.idp.attribute.resolver.ResolverDataConnectorDependency;
 import net.shibboleth.idp.attribute.resolver.ad.impl.SimpleAttributeDefinition;
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.idp.attribute.resolver.logic.ResolutionLabelPredicate;
 import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.ad.impl.SimpleAttributeDefinitionParser;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
@@ -119,10 +122,10 @@ public class SimpleAttributeParserTest extends BaseAttributeDefinitionParserTest
         placeholderConfig.setPropertySources(propertySources);
         context.addBeanFactoryPostProcessor(placeholderConfig);
 
-        AttributeDefinition attr = getAttributeDefn("resolver/relyingParties.xml", SimpleAttributeDefinition.class, context);
-        RelyingPartyIdPredicate pre = (RelyingPartyIdPredicate) attr.getActivationCondition();
-        ProfileRequestContext prc = new ProfileRequestContext();
-        RelyingPartyContext rpContext = prc.getSubcontext(RelyingPartyContext.class, true);
+        final AttributeDefinition attr = getAttributeDefn("resolver/relyingParties.xml", SimpleAttributeDefinition.class, context);
+        final RelyingPartyIdPredicate pre = (RelyingPartyIdPredicate) attr.getActivationCondition();
+        final ProfileRequestContext prc = new ProfileRequestContext();
+        final RelyingPartyContext rpContext = prc.getSubcontext(RelyingPartyContext.class, true);
         rpContext.setRelyingPartyId("p1");
         assertTrue(pre.test(prc));
         rpContext.setRelyingPartyId("p2 p3");
@@ -130,4 +133,74 @@ public class SimpleAttributeParserTest extends BaseAttributeDefinitionParserTest
         rpContext.setRelyingPartyId("p3");
         assertTrue(pre.test(prc));
     }
-}
+
+    @Test public void resolutionPhases() throws ComponentInitializationException {
+        final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+        final MutablePropertySources propertySources = context.getEnvironment().getPropertySources();
+        final MockPropertySource mockEnvVars = new MockPropertySource();
+        mockEnvVars.setProperty("prop1", "p1");
+        mockEnvVars.setProperty("prop2", "p2 p3");
+        mockEnvVars.setProperty("prop3", "");
+        propertySources.replace(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, mockEnvVars);
+
+        final PropertySourcesPlaceholderConfigurer placeholderConfig = new PropertySourcesPlaceholderConfigurer();
+        placeholderConfig.setPlaceholderPrefix("%{");
+        placeholderConfig.setPlaceholderSuffix("}");
+        placeholderConfig.setPropertySources(propertySources);
+        context.addBeanFactoryPostProcessor(placeholderConfig);
+
+        final AttributeDefinition attr = getAttributeDefn("resolver/resolutionPhases.xml", SimpleAttributeDefinition.class, context);
+        final ResolutionLabelPredicate pre = (ResolutionLabelPredicate) attr.getActivationCondition();
+        final ProfileRequestContext prc = new ProfileRequestContext();
+        final AttributeResolutionContext resContext = prc.getSubcontext(AttributeResolutionContext.class, true);
+        resContext.setResolutionLabel("p1");
+        assertTrue(pre.test(prc));
+        resContext.setResolutionLabel("p2 p3");
+        assertFalse(pre.test(prc));
+        resContext.setResolutionLabel("p3");
+        assertTrue(pre.test(prc));
+    }
+    
+    @Test public void phasesAndParties() throws ComponentInitializationException {
+        final GenericApplicationContext context = new FilesystemGenericApplicationContext();
+        final MutablePropertySources propertySources = context.getEnvironment().getPropertySources();
+        final MockPropertySource mockEnvVars = new MockPropertySource();
+        mockEnvVars.setProperty("prop1", "p1");
+        mockEnvVars.setProperty("prop2", "p2 p3");
+        mockEnvVars.setProperty("prop3", "");
+        propertySources.replace(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, mockEnvVars);
+
+        final PropertySourcesPlaceholderConfigurer placeholderConfig = new PropertySourcesPlaceholderConfigurer();
+        placeholderConfig.setPlaceholderPrefix("%{");
+        placeholderConfig.setPlaceholderSuffix("}");
+        placeholderConfig.setPropertySources(propertySources);
+        context.addBeanFactoryPostProcessor(placeholderConfig);
+
+        final AttributeDefinition attr = getAttributeDefn("resolver/phasesAndParties.xml", SimpleAttributeDefinition.class, context);
+        final Predicate<ProfileRequestContext> pre = attr.getActivationCondition();
+        final ProfileRequestContext prc = new ProfileRequestContext();
+        final RelyingPartyContext rpContext = prc.getSubcontext(RelyingPartyContext.class, true);
+        final AttributeResolutionContext resContext = prc.getSubcontext(AttributeResolutionContext.class, true);
+        
+        rpContext.setRelyingPartyId("p1");
+        assertFalse(pre.test(prc));
+        rpContext.setRelyingPartyId("p2 p3");
+        assertFalse(pre.test(prc));
+        rpContext.setRelyingPartyId("p3");
+        assertFalse(pre.test(prc));
+        
+        rpContext.setRelyingPartyId(null);
+        
+        resContext.setResolutionLabel("p1");
+        assertFalse(pre.test(prc));
+        resContext.setResolutionLabel("p2 p3");
+        assertFalse(pre.test(prc));
+        resContext.setResolutionLabel("p3");
+        assertFalse(pre.test(prc));
+        
+        rpContext.setRelyingPartyId("p3");
+        resContext.setResolutionLabel("p3");
+        assertTrue(pre.test(prc));
+    }
+
+}
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/phasesAndParties.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/phasesAndParties.xml
new file mode 100644
index 000000000..3680dfb26
--- /dev/null
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/phasesAndParties.xml
@@ -0,0 +1,9 @@
+ <AttributeDefinition 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xmlns="urn:mace:shibboleth:2.0:resolver"
+    xsi:type="Simple" id="attry"
+    relyingParties="%{prop1} %{prop2} %{prop3}"
+    resolutionPhases="%{prop1} %{prop2} %{prop3}"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+    <InputAttributeDefinition ref="fii"/>
+</AttributeDefinition>
\ No newline at end of file
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/resolutionPhases.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/resolutionPhases.xml
new file mode 100644
index 000000000..0413c0ecc
--- /dev/null
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/ad/resolver/resolutionPhases.xml
@@ -0,0 +1,8 @@
+ <AttributeDefinition 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+    xmlns="urn:mace:shibboleth:2.0:resolver"
+    xsi:type="Simple" id="attry"    
+    resolutionPhases="%{prop1} %{prop2} %{prop3}"
+    xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd">
+    <InputAttributeDefinition ref="fii"/>
+</AttributeDefinition>
\ No newline at end of file
diff --git a/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd b/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
index 28a2b8a56..e5ab13afa 100644
--- a/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
+++ b/idp-schema/src/main/resources/schema/shibboleth-attribute-resolver.xsd
@@ -3,7 +3,7 @@
 	xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
 	xmlns:sec="urn:mace:shibboleth:2.0:security"
 	targetNamespace="urn:mace:shibboleth:2.0:resolver"
-	elementFormDefault="qualified" version="4.0">
+	elementFormDefault="qualified" version="4.1">
 
     <import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
     <import namespace="urn:mace:shibboleth:2.0:security" schemaLocation="http://shibboleth.net/schema/idp/shibboleth-security.xsd"/>
@@ -201,16 +201,24 @@
         <attribute name="activationConditionRef" type="resolver:string">
             <annotation>
                 <documentation>
-                    A reference to a predicate to decide whether this plugin is applicable
-                    Mutually exclusive with relyingParties
+                    A reference to a predicate to decide whether this plugin is applicable.
+                    Mutually exclusive with relyingParties and resolutionPhases.
                 </documentation>
             </annotation>
         </attribute>
         <attribute name="relyingParties" type="resolver:string">
             <annotation>
                 <documentation>
-                    A (space separated) list of entities for which this plugin is to be active
-                    Mutually exclusive with activationConditionRef
+                    A (space separated) list of entities for which this plugin is to be active.
+                    Mutually exclusive with activationConditionRef.
+                </documentation>
+            </annotation>
+        </attribute>
+        <attribute name="resolutionPhases" type="resolver:string">
+            <annotation>
+                <documentation>
+                    A (space separated) list of resolution "phases" for which this plugin is to be active.
+                    Mutually exclusive with activationConditionRef.
                 </documentation>
             </annotation>
         </attribute>

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


More information about the commits mailing list