[java-opensaml] branch main updated: OSJ-438 - NameIDFormat filter won't remove if no formats supplied

Codeberg noreply at shibboleth.net
Tue Jan 20 19:06:25 UTC 2026


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

codeberg pushed a commit to branch main
in repository java-opensaml.

View the commit online:
https://codeberg.org/Shibboleth/java-opensaml/commit/fc1d67950bbed889d3bce82a88970da0acded08c

The following commit(s) were added to refs/heads/main by this push:
     new fc1d67950 OSJ-438 - NameIDFormat filter won't remove if no formats supplied
fc1d67950 is described below

commit fc1d67950bbed889d3bce82a88970da0acded08c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jan 20 14:05:40 2026 -0500

    OSJ-438 - NameIDFormat filter won't remove if no formats supplied
    
    https://shibboleth.atlassian.net/browse/OSJ-438
    
    Unit test added.
---
 .../resolver/filter/impl/NameIDFormatFilter.java     | 16 +++++++++++++---
 .../resolver/filter/impl/NameIDFormatFilterTest.java | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
index 09bb9035d..abd11fce5 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
@@ -41,6 +41,8 @@ import org.slf4j.Logger;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 
+import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
@@ -54,6 +56,9 @@ import net.shibboleth.shared.primitive.StringSupport;
  */
 public class NameIDFormatFilter extends AbstractMetadataFilter {
 
+    /** Used as a value in place of an empty collection when removing only. */
+    @Nonnull @NotEmpty private static String GUARD_VALUE = "_EMPTY";
+    
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(NameIDFormatFilter.class);
 
@@ -99,7 +104,9 @@ public class NameIDFormatFilter extends AbstractMetadataFilter {
         applyMap = ArrayListMultimap.create(rules.size(), 1);
         for (final Map.Entry<Predicate<EntityDescriptor>,Collection<String>> entry : rules.entrySet()) {
             if (entry.getKey() != null && entry.getValue() != null) {
-                applyMap.putAll(entry.getKey(), StringSupport.normalizeStringCollection(entry.getValue()));
+                final Collection<String> normalized = StringSupport.normalizeStringCollection(entry.getValue());
+                applyMap.putAll(entry.getKey(),
+                        normalized.isEmpty() ? CollectionSupport.singletonList(GUARD_VALUE) : normalized);
             }
         }
     }
@@ -128,7 +135,7 @@ public class NameIDFormatFilter extends AbstractMetadataFilter {
      */
     protected void filterEntityDescriptor(@Nonnull final EntityDescriptor descriptor) {
         for (final Map.Entry<Predicate<EntityDescriptor>,Collection<String>> entry : applyMap.asMap().entrySet()) {
-            if (!entry.getValue().isEmpty() && entry.getKey().test(descriptor)) {
+            if ((removeExistingFormats || !entry.getValue().isEmpty()) && entry.getKey().test(descriptor)) {
                 for (final RoleDescriptor role : descriptor.getRoleDescriptors()) {
                     assert role != null;
                     filterRoleDescriptor(role, entry.getValue());
@@ -175,7 +182,10 @@ public class NameIDFormatFilter extends AbstractMetadataFilter {
                 roleFormats.stream().map(NameIDFormat::getURI).collect(Collectors.toUnmodifiableSet());
         
         for (final String format : formats) {
-            if (existingFormats.contains(format)) {
+            if (GUARD_VALUE.equals(format)) {
+                // Skip guard value, only used to implement possibly empty mapping for removal.
+                continue;
+            } else if (existingFormats.contains(format)) {
                 log.debug("Ignoring add of existing NameIDFormat '{}' on EntityDescriptor '{}'", format, entityID);
             } else {
                 final NameIDFormat nif = formatBuilder.buildObject();
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
index bc9a2fef8..82d48ce71 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
@@ -93,6 +93,26 @@ public class NameIDFormatFilterTest extends XMLObjectBaseTestCase implements Pre
         Assert.assertEquals(role.getNameIDFormats().size(), 1);
     }
 
+    @Test
+    public void testRemovalOnly() throws ComponentInitializationException, ResolverException {
+        
+        metadataFilter.setRules(CollectionSupport.singletonMap(this, CollectionSupport.emptyList()));
+        metadataFilter.setRemoveExistingFormats(true);
+        metadataFilter.initialize();
+        
+        metadataProvider.setMetadataFilter(metadataFilter);
+        metadataProvider.setId("test");
+        metadataProvider.initialize();
+
+        EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
+        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
+        assert entity != null;
+        
+        SPSSODescriptor role = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+        assert role != null;
+        Assert.assertTrue(role.getNameIDFormats().isEmpty());
+    }
+
     @Test
     public void testWithRemoval() throws ComponentInitializationException, ResolverException {
         

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


More information about the commits mailing list