[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