[java-opensaml] branch master updated: IDP-1475 Handle XMLObjects with multiple String representations

Rod Widdowson rdw at steadingsoftware.com
Thu Aug 1 09:00:48 EDT 2019


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

rdw 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=e5afe7220b32baf43e93b4134651ff1881bd8e60

The following commit(s) were added to refs/heads/master by this push:
       new  e5afe72   IDP-1475 Handle XMLObjects with multiple String representations
e5afe72 is described below

commit e5afe7220b32baf43e93b4134651ff1881bd8e60
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Thu Aug 1 14:00:16 2019 +0100

    IDP-1475 Handle XMLObjects with multiple String representations
    
    https://issues.shibboleth.net/jira/browse/IDP-1475
---
 .../profile/logic/EntityAttributesPredicate.java   | 41 +++++++++++++++-------
 .../logic/EntityAttributesPredicateTest.java       | 13 +++++++
 .../impl/EntitiesDescriptor-Name-metadata.xml      | 16 +++++++++
 3 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicate.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicate.java
index 115bf6d..bc73a6c 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicate.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicate.java
@@ -362,13 +362,11 @@ public class EntityAttributesPredicate implements Predicate<EntityDescriptor> {
                 if (a.getName() != null && a.getName().equals(input.getName())
                         && (input.getNameFormat() == null || input.getNameFormat().equals(a.getNameFormat()))) {
 
+                    final List<String> attributeValues = getPossibleAttributeValuesAsStrings(a);
                     // Check each tag value's simple content for a value match.
                     for (int tagindex = 0; tagindex < tagvals.size(); ++tagindex) {
                         final String tagvalstr = tagvals.get(tagindex);
-
-                        final List<XMLObject> cvals = a.getAttributeValues();
-                        for (final XMLObject cval : cvals) {
-                            final String cvalstr = xmlObjectToString(cval);
+                        for (final String cvalstr: attributeValues) {
                             if (tagvalstr != null && cvalstr != null) {
                                 if (tagvalstr.equals(cvalstr)) {
                                     log.trace("Matched Entity Attribute ({}:{}) value {}", a.getNameFormat(),
@@ -389,10 +387,7 @@ public class EntityAttributesPredicate implements Predicate<EntityDescriptor> {
 
                     // Check each tag regular expression for a match.
                     for (int tagindex = 0; tagindex < tagexps.size(); ++tagindex) {
-
-                        final List<XMLObject> cvals = a.getAttributeValues();
-                        for (final XMLObject cval : cvals) {
-                            final String cvalstr = xmlObjectToString(cval);
+                        for (final String cvalstr: attributeValues) {
                             if (tagexps.get(tagindex) != null && cvalstr != null) {
                                 if (tagexps.get(tagindex).matcher(cvalstr).matches()) {
                                     log.trace("Matched Entity Attribute ({}:{}) value {}", a.getNameFormat(),
@@ -421,21 +416,39 @@ public class EntityAttributesPredicate implements Predicate<EntityDescriptor> {
             return true;
         }
 // Checkstyle: MethodLength ON
+
+        /** Get all possible strings values for the attribute.  This copes with the fact that
+         * an attribute can return multiple values {@link Attribute#getAttributeValues()} and that some
+         * type of value can have multiple values (for instance a boolean can be 1/0/true/false).
+         *
+         * @param attribute what to inspect
+         * @return all possible values, as string.
+         */
+        @Nonnull List<String> getPossibleAttributeValuesAsStrings(final @Nonnull Attribute attribute) {
+            final List<XMLObject> cvals = attribute.getAttributeValues();
+            final List<String> result = new ArrayList<String>(cvals.size()*2);
+            for (final XMLObject cval : cvals) {
+                result.addAll(xmlObjectToStrings(cval));
+            }
+            return result;
+        }
      
         /**
-         * Convert an XMLObject to a String if the type of recognized.
+         * Convert an XMLObject to an array of String which can represent the type, if recognized.
          * 
          * @param object object to convert
          * @return the converted value, or null
          */
-        @Nullable private String xmlObjectToString(@Nonnull final XMLObject object) {
+        @Nullable private List<String> xmlObjectToStrings(@Nonnull final XMLObject object) {
             String toMatch = null;
+            String toMatchAlt = null;
             if (object instanceof XSString) {
                 toMatch = ((XSString) object).getValue();
             } else if (object instanceof XSURI) {
                 toMatch = ((XSURI) object).getValue();
             } else if (object instanceof XSBoolean) {
                 toMatch = ((XSBoolean) object).getValue().getValue() ? "1" : "0";
+                toMatchAlt = ((XSBoolean) object).getValue().getValue() ? "true" : "false";
             } else if (object instanceof XSInteger) {
                 toMatch = ((XSInteger) object).getValue().toString();
             } else if (object instanceof XSDateTime) {
@@ -451,12 +464,14 @@ public class EntityAttributesPredicate implements Predicate<EntityDescriptor> {
                     toMatch = wc.getTextContent();
                 }
             }
-            if (toMatch != null) {
-                return toMatch;
+            if (toMatchAlt != null) {
+                return List.of(toMatch, toMatchAlt);
+            } else if (toMatch != null) {
+                return Collections.singletonList(toMatch);
             }
             log.warn("Unrecognized XMLObject type ({}), unable to convert to a string for comparison",
                     object.getClass().getName());
-            return null;
+            return Collections.emptyList();
         }
     }
 // Checkstyle: CyclomaticComplexity OFF
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicateTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicateTest.java
index cdad546..607868e 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicateTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/EntityAttributesPredicateTest.java
@@ -114,6 +114,19 @@ public class EntityAttributesPredicateTest extends XMLObjectBaseTestCase {
     }
     
     @Test
+    public void testIdP1475()  throws Exception {
+        final Candidate candidate = new Candidate("https://its.umich.edu/identity/activationCondition/isMemberOf");
+        candidate.setValues(Collections.singletonList("true"));
+        final EntityAttributesPredicate condition =
+                new EntityAttributesPredicate(Collections.singletonList(candidate));
+
+        final EntityDescriptor entity =
+                metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-1475.example.org")));
+        Assert.assertNotNull(entity);
+        Assert.assertTrue(condition.test(entity));
+    }
+
+    @Test
     public void testGroupAdditional() throws Exception {
 
         final Candidate candidate = new Candidate("urn:foo", Attribute.URI_REFERENCE);
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 6955bbc..ade948b 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
@@ -2,6 +2,8 @@
 <EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
         xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"
         xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
         Name="GroupTop" validUntil="2100-01-01T00:00:00Z">
 
     <Extensions>
@@ -25,6 +27,20 @@
         </IDPSSODescriptor>
     </EntityDescriptor>
 
+    <EntityDescriptor entityID="https://idp-1475.example.org">
+        <Extensions>
+            <mdattr:EntityAttributes>
+                <saml2:Attribute Name=" https://its.umich.edu/identity/activationCondition/isMemberOf"
+                                 NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
+                    <saml2:AttributeValue xsi:type="xsd:boolean">true</saml2:AttributeValue>
+                </saml2:Attribute>
+            </mdattr:EntityAttributes>
+        </Extensions>
+        <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"/>
+        </IDPSSODescriptor>
+    </EntityDescriptor>
+
     <EntitiesDescriptor Name="GroupSub1" validUntil="2100-01-01T00:00:00Z">
         <EntityDescriptor entityID="https://idp-sub1.example.org">
             <Extensions>

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


More information about the commits mailing list