[java-identity-provider] 04/04: IDP-1456 Add a ScopesNodeProcessor

Rod Widdowson rdw at steadingsoftware.com
Sat May 25 11:29:25 EDT 2019


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

rdw 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=75b91db7928219390b7ed7ca196443cddb4ac409

commit 75b91db7928219390b7ed7ca196443cddb4ac409
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Sat May 25 16:23:29 2019 +0100

    IDP-1456 Add a ScopesNodeProcessor
    
    https://issues.shibboleth.net/jira/browse/IDP-1456
    
    Adds a ScopesContainer, if relevant to EntityDescriptors and RoleDescriptors
---
 .../saml/metadata/impl/ScopesNodeProcessor.java    |  81 +++++++++++++
 .../metadata/impl/ScopesNodeProcessorTest.java     | 126 +++++++++++++++++++++
 .../metadata/Scopes-NodeProcessor-metadata.xml     |  38 +++++++
 3 files changed, 245 insertions(+)

diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessor.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessor.java
new file mode 100644
index 0000000..6bc907c
--- /dev/null
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessor.java
@@ -0,0 +1,81 @@
+/*
+ * 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.saml.metadata.impl;
+
+import java.util.HashSet;
+import java.util.List;
+
+import javax.annotation.concurrent.NotThreadSafe;
+
+import org.opensaml.core.xml.XMLObject;
+import org.opensaml.saml.metadata.resolver.filter.FilterException;
+import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
+import org.opensaml.saml.saml2.metadata.AttributeConsumingService;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.Extensions;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
+
+import net.shibboleth.idp.saml.metadata.ScopesContainer;
+import net.shibboleth.idp.saml.xmlobject.Scope;
+
+/**
+ * An implementation of {@link MetadataNodeProcessor} which extracts {@link Scope}s from any
+ * {@link AttributeConsumingService} or {@link EntityDescriptor}.  They are accumulated and stored
+ * back in as a {@link ScopesContainer}.
+ */
+ at NotThreadSafe
+public class ScopesNodeProcessor implements MetadataNodeProcessor {
+  
+    /** {@inheritDoc} */
+    @Override public void process(final XMLObject metadataNode) throws FilterException {
+        
+        final Extensions extensions;
+        if (metadataNode instanceof EntityDescriptor) {
+           extensions = ((EntityDescriptor) metadataNode).getExtensions();
+        } else if  (metadataNode instanceof RoleDescriptor) {
+            extensions = ((RoleDescriptor) metadataNode).getExtensions();
+        } else {
+            return;
+        }
+        if (extensions == null) {
+            return;
+        }
+
+        final List<XMLObject> scopes = extensions.getUnknownXMLObjects(Scope.DEFAULT_ELEMENT_NAME);
+        if (scopes.isEmpty()) {
+            return;
+        }
+
+        final HashSet<String> nonRegexScopes = new HashSet<>(scopes.size());
+        final HashSet<String> regexScopes = new HashSet<>(scopes.size());
+        for (final XMLObject object: scopes) {
+            final Scope scope = (Scope) object;
+            if (scope.getRegexp() != null && scope.getRegexp().booleanValue()) {
+                regexScopes.add(scope.getValue());
+            } else {
+                nonRegexScopes.add(scope.getValue());
+            }
+        }
+
+        final ScopesContainer container = new ScopesContainer();
+        container.setRegexpScopes(regexScopes);
+        container.setSimpleScopes(nonRegexScopes);
+        metadataNode.getObjectMetadata().put(container);
+    }
+
+}
\ No newline at end of file
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessorTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessorTest.java
new file mode 100644
index 0000000..c03a5c2
--- /dev/null
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/metadata/impl/ScopesNodeProcessorTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.saml.metadata.impl;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+
+import org.opensaml.core.criterion.EntityIdCriterion;
+import org.opensaml.core.xml.XMLObjectBaseTestCase;
+import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
+import org.opensaml.saml.metadata.resolver.filter.impl.NodeProcessingMetadataFilter;
+import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver;
+import org.opensaml.saml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.saml.metadata.ScopesContainer;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
+import net.shibboleth.utilities.java.support.resolver.ResolverException;
+
+public final class ScopesNodeProcessorTest extends XMLObjectBaseTestCase {
+    
+    private MetadataResolver resolver;
+    
+    @BeforeClass
+    public void getMetadataResolver() throws URISyntaxException, ComponentInitializationException, ResolverException {
+        final URL mdURL = ScopesNodeProcessorTest.class
+                .getResource("/net/shibboleth/idp/saml/impl/metadata/Scopes-NodeProcessor-metadata.xml");
+        final File mdFile = new File(mdURL.toURI());
+
+        final List<MetadataNodeProcessor> processors = List.of(new ScopesNodeProcessor());
+        
+        final NodeProcessingMetadataFilter metadataFilter = new NodeProcessingMetadataFilter();
+        metadataFilter.setNodeProcessors(processors);
+        metadataFilter.initialize();
+        
+        final FilesystemMetadataResolver fileResolver = new FilesystemMetadataResolver(mdFile);
+        fileResolver.setParserPool(parserPool);
+        fileResolver.setMetadataFilter(metadataFilter);
+        fileResolver.setId("test");
+        fileResolver.initialize();
+        resolver = fileResolver;
+    }
+    
+    @Test
+    public void noScopes() throws ResolverException {
+        
+        final EntityDescriptor noScopes  = resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://noscopes.example.org")));
+        assertTrue(noScopes.getObjectMetadata().get(ScopesContainer.class).isEmpty());
+        final AttributeAuthorityDescriptor aaNoScope = noScopes.getAttributeAuthorityDescriptor("urn:oasis:names:tc:SAML:2.0:protocol");
+        assertTrue(aaNoScope.getObjectMetadata().get(ScopesContainer.class).isEmpty());
+        final IDPSSODescriptor idpSSONoScope = noScopes.getIDPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol");
+        assertTrue(idpSSONoScope.getObjectMetadata().get(ScopesContainer.class).isEmpty());
+    }
+    
+    @Test 
+    public void scopes() throws ResolverException {
+        final EntityDescriptor entity  = resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://scopes.example.org")));
+
+        final List<ScopesContainer> entityList = entity.getObjectMetadata().get(ScopesContainer.class);
+        assertEquals(entityList.size(),1);
+        final ScopesContainer entityContainer = entityList.get(0);
+        /* 
+            <shibmd:Scope>entityScope</shibmd:Scope>
+            <shibmd:Scope>entityScope2</shibmd:Scope>
+         */
+        assertFalse(entityContainer.matchesScope("flibby"));
+        assertFalse(entityContainer.matchesScope("entityScope1"));
+        assertFalse(entityContainer.matchesScope("2entityScope2"));
+        assertTrue(entityContainer.matchesScope("entityScope"));
+        assertTrue(entityContainer.matchesScope("entityScope2"));
+        
+        final IDPSSODescriptor idpSSO = entity.getIDPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol");
+        final List<ScopesContainer> idpSSOList = idpSSO.getObjectMetadata().get(ScopesContainer.class);
+        assertEquals(idpSSOList.size(),1);
+        final ScopesContainer idpSSOContainer = idpSSOList.get(0);
+        /*
+            <shibmd:Scope regexp="true">^.*IDPSSO.*reg.*Scope</shibmd:Scope>
+            <shibmd:Scope regexp="false">IDPSSOScope2</shibmd:Scope>
+         */
+        assertFalse(idpSSOContainer.matchesScope("flibby"));
+        assertFalse(idpSSOContainer.matchesScope("FFFIDPSSOPREregSSScoped"));
+        assertTrue(idpSSOContainer.matchesScope("FFFIDPSSOPREregSSScope"));
+        assertTrue(idpSSOContainer.matchesScope("IDPSSOScope2"));
+        
+        final AttributeAuthorityDescriptor aa = entity.getAttributeAuthorityDescriptor("urn:oasis:names:tc:SAML:2.0:protocol");
+        final List<ScopesContainer> aaList = aa.getObjectMetadata().get(ScopesContainer.class);
+        assertEquals(aaList.size(),1);
+        final ScopesContainer aaContainer = aaList.get(0);
+        /*
+            <shibmd:Scope regexp="false">AAScope1</shibmd:Scope>
+            <shibmd:Scope regexp="true">^.*AASCOPE2.*</shibmd:Scope>
+         */
+        assertFalse(aaContainer.matchesScope("flibby"));
+        assertTrue(aaContainer.matchesScope("AAScope1"));
+        assertTrue(aaContainer.matchesScope("AASCOPE2"));
+        assertTrue(aaContainer.matchesScope("flibbyAASCOPE2flibby"));
+        
+    }
+
+}
diff --git a/idp-saml-impl/src/test/resources/net/shibboleth/idp/saml/impl/metadata/Scopes-NodeProcessor-metadata.xml b/idp-saml-impl/src/test/resources/net/shibboleth/idp/saml/impl/metadata/Scopes-NodeProcessor-metadata.xml
new file mode 100644
index 0000000..8167928
--- /dev/null
+++ b/idp-saml-impl/src/test/resources/net/shibboleth/idp/saml/impl/metadata/Scopes-NodeProcessor-metadata.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0"
+            xsi:schemaLocation="urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd
+                                urn:mace:shibboleth:metadata:1.0 classpath:\schema\shibboleth-metadata-1.0.xsd"
+             Name="GroupTop" validUntil="2100-01-01T00:00:00Z">
+
+    <EntityDescriptor entityID="https://noscopes.example.org">
+        <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+            <Extensions/>
+            <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://idp.example.org/idp/Shibboleth/SSO"/>
+        </IDPSSODescriptor>
+        <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+            <Extensions>
+                <shibmd:KeyAuthority/>
+            </Extensions>
+        </AttributeAuthorityDescriptor>
+    </EntityDescriptor>
+
+    <EntityDescriptor entityID="https://scopes.example.org">
+        <Extensions>
+            <shibmd:Scope>entityScope</shibmd:Scope>
+            <shibmd:Scope>entityScope2</shibmd:Scope>
+        </Extensions>
+        <IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+            <Extensions>
+                <shibmd:Scope regexp="true">^.*IDPSSO.*reg.*Scope</shibmd:Scope>
+                <shibmd:Scope regexp="false">IDPSSOScope2</shibmd:Scope>
+            </Extensions>
+            <SingleSignOnService Binding="urn:mace:shibboleth:1.0:profiles:AuthnRequest" Location="https://idp.example.org/idp/Shibboleth/SSO"/>
+        </IDPSSODescriptor>
+        <AttributeAuthorityDescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+            <Extensions>
+                <shibmd:Scope regexp="false">AAScope1</shibmd:Scope>
+                <shibmd:Scope regexp="true">^.*AASCOPE2.*</shibmd:Scope>
+            </Extensions>
+        </AttributeAuthorityDescriptor>
+    </EntityDescriptor>   
+</EntitiesDescriptor>

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


More information about the commits mailing list