[java-shib-attribute] 02/02: JSATTR-27 - velocity template encoding

Daniel Fisher dfisher at vt.edu
Sun Jun 16 14:05:21 UTC 2024


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

dfisher pushed a commit to branch dev/jsattr-27-ldap-utf8
in repository java-shib-attribute.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=a2a1b624a6614d2a2f8efcf965eb2f75cb14bd68

commit a2a1b624a6614d2a2f8efcf965eb2f75cb14bd68
Author: Daniel Fisher <dfisher at vt.edu>
AuthorDate: Sun Jun 16 10:02:21 2024 -0400

    JSATTR-27 - velocity template encoding
    
    Change filter template encoding from US_ASCII to UTF_8.
    Add unit tests for multi-byte characters in the filter.
    
    https://shibboleth.atlassian.net/browse/JSATTR-27
---
 .../TemplatedExecutableSearchFilterBuilder.java    |   3 +-
 .../resolver/dc/ldap/impl/LDAPDataConnector.java   |   2 +-
 .../dc/ldap/impl/LDAPDataConnectorTest.java        | 130 ++++++++++++++++++++-
 .../impl/dc/ldap/ldapDataConnectorTest.ldif        |  18 +++
 4 files changed, 150 insertions(+), 3 deletions(-)

diff --git a/shib-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java b/shib-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
index 3073c1b50..9b248fe1e 100644
--- a/shib-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
+++ b/shib-attribute-resolver-api/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/TemplatedExecutableSearchFilterBuilder.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.attribute.resolver.dc.ldap;
 
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -176,7 +177,7 @@ public class TemplatedExecutableSearchFilterBuilder extends AbstractExecutableSe
                     "TemplatedExecutableStatementBuilder: template text must be non null");
         }
 
-        template = Template.fromTemplate(localEngine, localTemplateText);
+        template = Template.fromTemplate(localEngine, localTemplateText, StandardCharsets.UTF_8);
     }
 
     /** {@inheritDoc} */
diff --git a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
index 51aa0a1ee..7b2771eb6 100644
--- a/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
+++ b/shib-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnector.java
@@ -125,7 +125,7 @@ public class LDAPDataConnector extends AbstractSearchDataConnector<ExecutableSea
                 throw new ComponentInitializationException(getLogPrefix() + " No connection factory was configured");
             }
             if (searchOperation == null) {
-                throw new ComponentInitializationException(getLogPrefix() + " No search executor was configured");
+                throw new ComponentInitializationException(getLogPrefix() + " No search operation was configured");
             }
 
             if (defaultValidator) {
diff --git a/shib-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java b/shib-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
index 827a0ba50..f85bc1640 100644
--- a/shib-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
+++ b/shib-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/ldap/impl/LDAPDataConnectorTest.java
@@ -538,7 +538,135 @@ public class LDAPDataConnectorTest {
         assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("  ")));
         assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue(" philip.principal at shibboleth.net ")));
     }
-    
+
+    @Test public void resolveMultiByteCharacters() throws ComponentInitializationException, ResolutionException {
+        final ParameterizedExecutableSearchFilterBuilder builder =
+            newParameterizedExecutableSearchFilterBuilder(
+                "(&(uid={principalName})(description=März Äpfel))");
+
+        final DataConnector connector = createLdapDataConnector(builder, new StringAttributeValueMappingStrategy());
+        connector.initialize();
+
+        final AttributeResolutionContext context =
+            TestSources.createResolutionContext("RAPHAËL_WEIß", TestSources.IDP_ENTITY_ID,
+                TestSources.SP_ENTITY_ID);
+        final Map<String, IdPAttribute> attrs = connector.resolve(context);
+        assert attrs != null;
+
+        // check total attributes: uid, cn, sn, mail
+        assertEquals(attrs.size(), 4);
+        // check uid
+        assertEquals(attrs.get("uid").getValues().size(), 1);
+        assertEquals(attrs.get("uid").getValues().iterator().next(), new StringAttributeValue(
+            "RAPHAËL_WEIß"));
+        // check cn
+        assertEquals(attrs.get("cn").getValues().size(), 1);
+        assertTrue(attrs.get("cn").getValues().contains(new StringAttributeValue("Raphaël Weiß")));
+        // check sn
+        assertEquals(attrs.get("sn").getValues().size(), 1);
+        assertEquals(attrs.get("sn").getValues().iterator().next(), new StringAttributeValue("Weiß"));
+        // check mail
+        assertEquals(attrs.get("mail").getValues().size(), 2);
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaël.weiß@shibboleth.net")));
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaëlweiß@shibboleth.net")));
+    }
+
+    @Test public void resolveMultiByteCharactersEscape() throws ComponentInitializationException, ResolutionException {
+        final ParameterizedExecutableSearchFilterBuilder builder =
+            newParameterizedExecutableSearchFilterBuilder(
+                "(&(uid={principalName})(description=M\\C3\\A4rz \\C3\\84pfel))");
+
+        final DataConnector connector = createLdapDataConnector(builder, new StringAttributeValueMappingStrategy());
+        connector.initialize();
+
+        final AttributeResolutionContext context =
+            TestSources.createResolutionContext("RAPHAËL_WEIß", TestSources.IDP_ENTITY_ID,
+                TestSources.SP_ENTITY_ID);
+        final Map<String, IdPAttribute> attrs = connector.resolve(context);
+        assert attrs != null;
+
+        // check total attributes: uid, cn, sn, mail
+        assertEquals(attrs.size(), 4);
+        // check uid
+        assertEquals(attrs.get("uid").getValues().size(), 1);
+        assertEquals(attrs.get("uid").getValues().iterator().next(), new StringAttributeValue(
+            "RAPHAËL_WEIß"));
+        // check cn
+        assertEquals(attrs.get("cn").getValues().size(), 1);
+        assertTrue(attrs.get("cn").getValues().contains(new StringAttributeValue("Raphaël Weiß")));
+        // check sn
+        assertEquals(attrs.get("sn").getValues().size(), 1);
+        assertEquals(attrs.get("sn").getValues().iterator().next(), new StringAttributeValue("Weiß"));
+        // check mail
+        assertEquals(attrs.get("mail").getValues().size(), 2);
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaël.weiß@shibboleth.net")));
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaëlweiß@shibboleth.net")));
+    }
+
+    @Test public void resolveMultiByteCharactersVelocity() throws ComponentInitializationException, ResolutionException {
+        final TemplatedExecutableSearchFilterBuilder builder = new TemplatedExecutableSearchFilterBuilder();
+        builder.setTemplateText("(&(uid=${resolutionContext.principal})(description=März Äpfel))");
+        builder.setVelocityEngine(VelocityEngine.newVelocityEngine());
+        builder.initialize();
+        final DataConnector connector = createLdapDataConnector(builder, new StringAttributeValueMappingStrategy());
+        connector.initialize();
+
+        final AttributeResolutionContext context =
+            TestSources.createResolutionContext("RAPHAËL_WEIß", TestSources.IDP_ENTITY_ID,
+                TestSources.SP_ENTITY_ID);
+        final Map<String, IdPAttribute> attrs = connector.resolve(context);
+        assert attrs != null;
+
+        // check total attributes: uid, cn, sn, mail
+        assertEquals(attrs.size(), 4);
+        // check uid
+        assertEquals(attrs.get("uid").getValues().size(), 1);
+        assertEquals(attrs.get("uid").getValues().iterator().next(), new StringAttributeValue(
+            "RAPHAËL_WEIß"));
+        // check cn
+        assertEquals(attrs.get("cn").getValues().size(), 1);
+        assertTrue(attrs.get("cn").getValues().contains(new StringAttributeValue("Raphaël Weiß")));
+        // check sn
+        assertEquals(attrs.get("sn").getValues().size(), 1);
+        assertEquals(attrs.get("sn").getValues().iterator().next(), new StringAttributeValue("Weiß"));
+        // check mail
+        assertEquals(attrs.get("mail").getValues().size(), 2);
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaël.weiß@shibboleth.net")));
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaëlweiß@shibboleth.net")));
+    }
+
+    @Test public void resolveMultiByteCharactersEscapeVelocity() throws ComponentInitializationException, ResolutionException {
+        final TemplatedExecutableSearchFilterBuilder builder = new TemplatedExecutableSearchFilterBuilder();
+        builder.setTemplateText("(&(uid=${resolutionContext.principal})(description=M\\C3\\A4rz \\C3\\84pfel))");
+        builder.setVelocityEngine(VelocityEngine.newVelocityEngine());
+        builder.initialize();
+        final DataConnector connector = createLdapDataConnector(builder, new StringAttributeValueMappingStrategy());
+        connector.initialize();
+
+        final AttributeResolutionContext context =
+            TestSources.createResolutionContext("RAPHAËL_WEIß", TestSources.IDP_ENTITY_ID,
+                TestSources.SP_ENTITY_ID);
+        final Map<String, IdPAttribute> attrs = connector.resolve(context);
+        assert attrs != null;
+
+        // check total attributes: uid, cn, sn, mail
+        assertEquals(attrs.size(), 4);
+        // check uid
+        assertEquals(attrs.get("uid").getValues().size(), 1);
+        assertEquals(attrs.get("uid").getValues().iterator().next(), new StringAttributeValue(
+            "RAPHAËL_WEIß"));
+        // check cn
+        assertEquals(attrs.get("cn").getValues().size(), 1);
+        assertTrue(attrs.get("cn").getValues().contains(new StringAttributeValue("Raphaël Weiß")));
+        // check sn
+        assertEquals(attrs.get("sn").getValues().size(), 1);
+        assertEquals(attrs.get("sn").getValues().iterator().next(), new StringAttributeValue("Weiß"));
+        // check mail
+        assertEquals(attrs.get("mail").getValues().size(), 2);
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaël.weiß@shibboleth.net")));
+        assertTrue(attrs.get("mail").getValues().contains(new StringAttributeValue("raphaëlweiß@shibboleth.net")));
+    }
+
     @Nonnull public static ParameterizedExecutableSearchFilterBuilder newParameterizedExecutableSearchFilterBuilder(@Nonnull final String filter) throws ComponentInitializationException {
         final ParameterizedExecutableSearchFilterBuilder builder = new ParameterizedExecutableSearchFilterBuilder();
         builder.setSearchFilter(filter);
diff --git a/shib-attribute-resolver-impl/src/test/resources/net/shibboleth/idp/attribute/resolver/impl/dc/ldap/ldapDataConnectorTest.ldif b/shib-attribute-resolver-impl/src/test/resources/net/shibboleth/idp/attribute/resolver/impl/dc/ldap/ldapDataConnectorTest.ldif
index 73683a9d4..1ac970752 100644
--- a/shib-attribute-resolver-impl/src/test/resources/net/shibboleth/idp/attribute/resolver/impl/dc/ldap/ldapDataConnectorTest.ldif
+++ b/shib-attribute-resolver-impl/src/test/resources/net/shibboleth/idp/attribute/resolver/impl/dc/ldap/ldapDataConnectorTest.ldif
@@ -66,3 +66,21 @@ userpassword: changeit
 homephone: 555-222-5678
 mail: dlo1 at shibboleth.net
 description: test principal
+
+# dn: cn=Raphaël Weiß,ou=people,dc=shibboleth,dc=net
+dn:: Y249UmFwaGHDq2wgV2Vpw58sb3U9cGVvcGxlLGRjPXNoaWJib2xldGgsZGM9bmV0
+objectclass: inetOrgPerson
+# cn: Raphaël_Weiß
+cn:: UmFwaGHDq2wgV2Vpw58=
+# sn: Weiß
+sn:: V2Vpw58=
+# uid: RAPHAËL_WEIß
+uid:: UkFQSEHDi0xfV0VJw58=
+userpassword: changeit
+homephone: 555-111-4444
+# mail: raphaël.weiß@shibboleth.net
+mail:: cmFwaGHDq2wud2Vpw59Ac2hpYmJvbGV0aC5uZXQ=
+# mail: raphaëlweiß@shibboleth.net
+mail:: cmFwaGHDq2x3ZWnDn0BzaGliYm9sZXRoLm5ldA==
+# description: März Äpfel
+description:: TcOkcnogw4RwZmVs

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


More information about the commits mailing list