[java-opensaml] branch master updated: OSJ-170 - Add AffiliationDescriptor support to group predicate

Scott Cantor cantor.2 at osu.edu
Thu Aug 3 10:49:59 EDT 2017


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

scantor 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=50e75adc390b29b38a0378aa3df79d15bb2b5d63

The following commit(s) were added to refs/heads/master by this push:
       new  50e75ad   OSJ-170 - Add AffiliationDescriptor support to group predicate
50e75ad is described below

commit 50e75adc390b29b38a0378aa3df79d15bb2b5d63
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Aug 3 10:49:50 2017 -0400

    OSJ-170 - Add AffiliationDescriptor support to group predicate
    
    https://issues.shibboleth.net/jira/browse/OSJ-170
---
 .../profile/logic/EntityGroupNamePredicate.java    |  75 ++++++++++-
 .../logic/EntityGroupNamePredicateTest.java        | 137 +++++++++++++++++++++
 .../impl/EntitiesDescriptor-Name-metadata.xml      |   7 ++
 3 files changed, 214 insertions(+), 5 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicate.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicate.java
index f24d69b..7eb95fc 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicate.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicate.java
@@ -17,6 +17,7 @@
 
 package org.opensaml.saml.common.profile.logic;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -29,9 +30,17 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
 import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
 
+import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.saml.metadata.EntityGroupName;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.saml2.metadata.AffiliateMember;
+import org.opensaml.saml.saml2.metadata.AffiliationDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableSet;
@@ -42,9 +51,18 @@ import com.google.common.collect.ImmutableSet;
  */
 public class EntityGroupNamePredicate implements Predicate<EntityDescriptor> {
     
+    /** Class logger. */
+    @Nonnull private final Logger log = LoggerFactory.getLogger(EntityGroupNamePredicate.class);
+    
     /** Groups to match on. */
     @Nonnull @NonnullElements private final Set<String> groupNames;
     
+    /** A supplemental resolver to allow for {@link AffiliationDescriptor} lookup. */
+    @Nullable private MetadataResolver metadataResolver;
+    
+    /** Pre-created criteria sets for metadata lookup. */
+    @Nullable @NonnullElements private Collection<CriteriaSet> criteriaSets;
+    
     /**
      * Constructor.
      * 
@@ -61,6 +79,26 @@ public class EntityGroupNamePredicate implements Predicate<EntityDescriptor> {
             }
         }
     }
+    
+    /**
+     * Constructor.
+     * 
+     * @param names the group names to test for
+     * @param resolver metadata resolver for affiliation support
+     * 
+     * @since 3.4.0
+     */
+    public EntityGroupNamePredicate(@Nonnull @NonnullElements final Collection<String> names,
+            @Nonnull final MetadataResolver resolver) {
+        this(names);
+        
+        metadataResolver = Constraint.isNotNull(resolver, "MetadataResolver cannot be null");
+        
+        criteriaSets = new ArrayList<>(groupNames.size());
+        for (final String name : groupNames) {
+            criteriaSets.add(new CriteriaSet(new EntityIdCriterion(name)));
+        }
+    }
 
     /**
      * Get the group name criteria.
@@ -71,18 +109,45 @@ public class EntityGroupNamePredicate implements Predicate<EntityDescriptor> {
         return ImmutableSet.copyOf(groupNames);
     }
     
+// Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
     @Override
     public boolean apply(@Nullable final EntityDescriptor input) {
-        if (input != null) {
-            for (final EntityGroupName group : input.getObjectMetadata().get(EntityGroupName.class)) {
-                if (groupNames.contains(group.getName())) {
-                    return true;
+        
+        if (input == null) {
+            log.debug("Input was null, condition is false");
+            return false;
+        }
+        
+        for (final EntityGroupName group : input.getObjectMetadata().get(EntityGroupName.class)) {
+            if (groupNames.contains(group.getName())) {
+                log.debug("Found matching group '{}' attached to entity '{}'", group.getName(), input.getEntityID());
+                return true;
+            }
+        }
+        
+        if (metadataResolver != null) {
+            for (final CriteriaSet criteria : criteriaSets) {
+                try {
+                    final EntityDescriptor affiliation = metadataResolver.resolveSingle(criteria);
+                    if (affiliation != null && affiliation.getAffiliationDescriptor() != null) {
+                        for (final AffiliateMember member : affiliation.getAffiliationDescriptor().getMembers()) {
+                            if (member.getID().equals(input.getEntityID())) {
+                                log.debug("Found AffiliationDescriptor '{}' membership for entity '{}'",
+                                        affiliation.getEntityID(), input.getEntityID());
+                                return true;
+                            }
+                        }
+                    }
+                } catch (final ResolverException e) {
+                    log.warn("Metadata lookup for AffiliationDescriptor failed", e);
                 }
             }
         }
         
+        log.debug("No group match found for entity '{}'", input.getEntityID());
         return false;
     }
-
+// Checkstyle: CyclomaticComplexity ON
+    
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicateTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicateTest.java
new file mode 100644
index 0000000..7b50f4f
--- /dev/null
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityGroupNamePredicateTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.profile.logic;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import net.shibboleth.ext.spring.resource.ResourceHelper;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.core.xml.XMLObjectBaseTestCase;
+import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
+import org.opensaml.saml.metadata.resolver.filter.impl.EntitiesDescriptorNameProcessor;
+import org.opensaml.saml.metadata.resolver.filter.impl.NodeProcessingMetadataFilter;
+import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for {@link EntityGroupNamePredicate}.
+ */
+public class EntityGroupNamePredicateTest extends XMLObjectBaseTestCase {
+
+    private NodeProcessingMetadataFilter filter;
+    
+    private ResourceBackedMetadataResolver metadataProvider;
+    
+    @BeforeClass
+    protected void setUp() throws Exception {
+        
+        final Resource resource =
+                new ClassPathResource("/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml");
+        
+        filter = new NodeProcessingMetadataFilter();
+        filter.setNodeProcessors(Collections.<MetadataNodeProcessor>singletonList(new EntitiesDescriptorNameProcessor()));
+        filter.initialize();
+        
+        metadataProvider = new ResourceBackedMetadataResolver(null, ResourceHelper.of(resource));
+        metadataProvider.setId("test");
+        metadataProvider.setParserPool(parserPool);
+        metadataProvider.setMetadataFilter(filter);
+        metadataProvider.initialize();
+    }
+    
+    @AfterClass
+    protected void tearDown() {
+        metadataProvider.destroy();
+        filter.destroy();
+    }
+
+    @Test
+    public void testNoMatch() throws Exception {
+
+        final EntityGroupNamePredicate condition =
+                new EntityGroupNamePredicate(Collections.singletonList("GroupBad"), metadataProvider);
+                
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-top.example.org")));
+        Assert.assertNotNull(entity);
+        
+        Assert.assertFalse(condition.apply(entity));
+    }
+    
+    @Test
+    public void testGroupMatch() throws Exception {
+
+        final EntityGroupNamePredicate condition =
+                new EntityGroupNamePredicate(Collections.singletonList("GroupTop"), metadataProvider);
+                
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-top.example.org")));
+        Assert.assertNotNull(entity);
+        
+        Assert.assertTrue(condition.apply(entity));
+    }
+
+    @Test
+    public void testGroupsMatch() throws Exception {
+
+        final EntityGroupNamePredicate condition =
+                new EntityGroupNamePredicate(Arrays.asList("GroupBad", "GroupSub2"), metadataProvider);
+                
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-sub2a.example.org")));
+        Assert.assertNotNull(entity);
+        
+        Assert.assertTrue(condition.apply(entity));
+    }
+
+    @Test
+    public void testAffiliationMatch() throws Exception {
+
+        final EntityGroupNamePredicate condition =
+                new EntityGroupNamePredicate(Collections.singletonList("https://affiliation.example.org"), metadataProvider);
+                
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-sub2a.example.org")));
+        Assert.assertNotNull(entity);
+        
+        Assert.assertTrue(condition.apply(entity));
+    }
+
+    @Test
+    public void testAffiliationNoMatch() throws Exception {
+
+        final EntityGroupNamePredicate condition =
+                new EntityGroupNamePredicate(Collections.singletonList("https://affiliation.example.org"), metadataProvider);
+                
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-top.example.org")));
+        Assert.assertNotNull(entity);
+        
+        Assert.assertFalse(condition.apply(entity));
+    }
+
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml
index 244a13f..6955bbc 100644
--- a/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml
+++ b/opensaml-saml-impl/src/test/resources/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml
@@ -12,6 +12,13 @@
         </mdattr:EntityAttributes>
     </Extensions>
 
+    <EntityDescriptor entityID="https://affiliation.example.org">
+        <AffiliationDescriptor>
+            <AffiliateMember>foo</AffiliateMember>
+            <AffiliateMember>https://idp-sub2a.example.org</AffiliateMember>
+        </AffiliationDescriptor>
+    </EntityDescriptor>
+
     <EntityDescriptor entityID="https://idp-top.example.org">
         <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
             <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://idp.example.org/idp/Shibboleth/SSO"/>

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


More information about the commits mailing list