[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