[java-metadata-aggregator] branch main updated: MDA-288 - Add DuplicateEntityInAggregateCheckingStage

Ian Young ian at iay.org.uk
Fri Apr 14 14:57:24 UTC 2023


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

iay pushed a commit to branch main
in repository java-metadata-aggregator.

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

The following commit(s) were added to refs/heads/main by this push:
     new daf35de  MDA-288 - Add DuplicateEntityInAggregateCheckingStage
daf35de is described below

commit daf35de4e8c80701467ec45f1f330f2abcd34fb0
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Fri Apr 14 15:46:17 2023 +0100

    MDA-288 - Add DuplicateEntityInAggregateCheckingStage
    
    https://shibboleth.atlassian.net/browse/MDA-288
---
 .../DuplicateEntityInAggregateCheckingStage.java   | 81 ++++++++++++++++++++++
 .../resources/net/shibboleth/metadata/beans.xml    |  3 +
 ...uplicateEntityInAggregateCheckingStageTest.java | 39 +++++++++++
 ...ntityInAggregateCheckingStage-hasDuplicates.xml |  9 +++
 4 files changed, 132 insertions(+)

diff --git a/mda-framework/src/main/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage.java b/mda-framework/src/main/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage.java
new file mode 100644
index 0000000..100aa9b
--- /dev/null
+++ b/mda-framework/src/main/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage.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.metadata.dom.saml;
+
+import java.util.HashSet;
+
+import javax.annotation.Nonnull;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.pipeline.AbstractIteratingStage;
+import net.shibboleth.metadata.pipeline.StageProcessingException;
+import net.shibboleth.shared.xml.AttributeSupport;
+
+/**
+ * A stage which detects duplication of <code>entityID</code> values in
+ * SAML entity collections.
+ *
+ * <p>
+ * Any duplicate <code>entityID</code> results in an {@link ErrorStatus}
+ * being added to the item.
+ * </p>
+ *
+ * <p>
+ * Note that the stage operates on each item independently under the
+ * assumption that the stage is to be presented with a single item containing an
+ * <code>EntitiesDescriptor</code> aggregate of many individual entities as
+ * a final validity check prior to publication.
+ * </p>
+ */
+public class DuplicateEntityInAggregateCheckingStage extends AbstractIteratingStage<Element> {
+
+    @Override
+    protected void doExecute(final @Nonnull Item<Element> item)
+            throws StageProcessingException {
+        final @Nonnull Element element = item.unwrap();
+
+        // List all the relevant elements in this document in document order
+        final NodeList eList = element.getElementsByTagNameNS(SAMLMetadataSupport.MD_NS,
+                SAMLMetadataSupport.ENTITY_DESCRIPTOR_NAME.getLocalPart());
+
+        final @Nonnull var ids = new HashSet<String>();
+        final @Nonnull var reported = new HashSet<String>();
+        final var count = eList.getLength();
+        for (int eIndex = 0; eIndex < count; eIndex++) {
+            final Element entity = (Element) eList.item(eIndex);
+            assert entity != null;
+            final var id = AttributeSupport.getAttributeValue(entity, null, "entityID");
+            if (id != null) {
+                if (ids.contains(id)) {
+                    // Report duplicate, but only once.
+                    if (!reported.contains(id)) {
+                        item.getItemMetadata().put(new ErrorStatus(getId(), "duplicate entityID: " + id));
+                        reported.add(id);
+                    }
+                } else {
+                    ids.add(id);
+                }
+            }
+        }
+    }
+
+}
diff --git a/mda-framework/src/main/resources/net/shibboleth/metadata/beans.xml b/mda-framework/src/main/resources/net/shibboleth/metadata/beans.xml
index 47d4260..d71f356 100644
--- a/mda-framework/src/main/resources/net/shibboleth/metadata/beans.xml
+++ b/mda-framework/src/main/resources/net/shibboleth/metadata/beans.xml
@@ -126,6 +126,9 @@
     <bean id="mda.DiscoFeedCollectionSerializer" abstract="true" parent="mda.component_parent"
         class="net.shibboleth.metadata.dom.saml.DiscoFeedCollectionSerializer"/>
 
+    <bean id="mda.DuplicateEntityInAggregateCheckingStage" abstract="true" parent="mda.stage_parent"
+        class="net.shibboleth.metadata.dom.saml.DuplicateEntityInAggregateCheckingStage"/>
+
     <bean id="mda.EntitiesDescriptorAssemblerStage" abstract="true" parent="mda.stage_parent"
         class="net.shibboleth.metadata.dom.saml.EntitiesDescriptorAssemblerStage"/>
 
diff --git a/mda-framework/src/test/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStageTest.java b/mda-framework/src/test/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStageTest.java
new file mode 100644
index 0000000..d2255a1
--- /dev/null
+++ b/mda-framework/src/test/java/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStageTest.java
@@ -0,0 +1,39 @@
+package net.shibboleth.metadata.dom.saml;
+
+import java.util.HashSet;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.dom.testing.BaseDOMTest;
+import net.shibboleth.shared.collection.CollectionSupport;
+
+public class DuplicateEntityInAggregateCheckingStageTest extends BaseDOMTest {
+
+    protected DuplicateEntityInAggregateCheckingStageTest() {
+        super(DuplicateEntityInAggregateCheckingStage.class);
+    }
+
+    @Test
+    public void hasDuplicates() throws Exception {
+        final var item = readDOMItem("hasDuplicates.xml");
+        
+        final var stage = new DuplicateEntityInAggregateCheckingStage();
+        stage.setId("test");
+        stage.initialize();
+        stage.execute(CollectionSupport.listOf(item));
+        stage.destroy();
+        
+        final var errors = item.getItemMetadata().get(ErrorStatus.class);
+        Assert.assertEquals(errors.size(), 2);
+        
+        // The errors can appear in any order in the item metadata.
+        final var messages = new HashSet<String>();
+        for (final var error : errors) {
+            messages.add(error.getStatusMessage());
+        }
+        Assert.assertTrue(messages.contains("duplicate entityID: first"));
+        Assert.assertTrue(messages.contains("duplicate entityID: second"));
+    }
+}
diff --git a/mda-framework/src/test/resources/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage-hasDuplicates.xml b/mda-framework/src/test/resources/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage-hasDuplicates.xml
new file mode 100644
index 0000000..4c68f25
--- /dev/null
+++ b/mda-framework/src/test/resources/net/shibboleth/metadata/dom/saml/DuplicateEntityInAggregateCheckingStage-hasDuplicates.xml
@@ -0,0 +1,9 @@
+<EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+    <EntityDescriptor entityID="first"/>
+    <EntityDescriptor entityID="second"/>
+    <EntityDescriptor entityID="first"/>
+    <EntityDescriptor entityID="second"/>
+    <EntityDescriptor entityID="first"/>
+    <EntityDescriptor entityID="third"/>
+    <EntityDescriptor entityID="first"/>
+</EntitiesDescriptor>

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


More information about the commits mailing list