diff --git a/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java b/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java index d78159a8..5e959c19 100644 --- a/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java +++ b/core/src/main/java/org/springframework/ldap/core/DistinguishedName.java @@ -105,6 +105,15 @@ public class DistinguishedName implements Name { */ public static final String SPACED_DN_FORMAT_PROPERTY = "org.springframework.ldap.core.spacedDnFormat"; + /** + * System property that will be inspected to determine whether creating a + * DistinguishedName will leave the keys as they were in the original String + * or convert the keys to lowercase. Default is to convert the keys to + * lowercase. + * @since 1.3.1 + */ + public static final String PRESERVE_KEY_CASE_PROPERTY = "org.springframework.ldap.core.preserveKeyCase"; + private static final Log log = LogFactory.getLog(DistinguishedName.class); private static final boolean COMPACT = true; diff --git a/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java b/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java index cdd71ced..63fc60f5 100644 --- a/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java +++ b/core/src/main/java/org/springframework/ldap/core/LdapRdnComponent.java @@ -51,18 +51,29 @@ public class LdapRdnComponent implements Comparable, Serializable { /** * Constructs an LdapRdnComponent, optionally decoding the value. + *

+ * If the System property + * org.springframework.ldap.core.preserveKeyCase is set to + * "true", the keys will preserve their original case. Default is to convert + * them to lowercase. * - * @param key the Atttribute name. + * @param key the Attribute name. * @param value the Attribute value. * @param decodeValue if true the value is decoded (typically * used when a DN is parsed from a String), otherwise the value is used as * specified. + * @see DistinguishedName#PRESERVE_KEY_CASE_PROPERTY */ public LdapRdnComponent(String key, String value, boolean decodeValue) { Validate.notEmpty(key, "Key must not be empty"); Validate.notEmpty(value, "Value must not be empty"); - this.key = StringUtils.lowerCase(key); + String preserveKeyCase = System.getProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY); + if (StringUtils.isBlank(preserveKeyCase)) { + this.key = StringUtils.lowerCase(key); + } else { + this.key = key; + } if (decodeValue) { this.value = LdapEncoder.nameDecode(value); } diff --git a/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java b/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java index 4fbd587b..34c5fc06 100644 --- a/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java +++ b/core/src/test/java/org/springframework/ldap/core/DistinguishedNameTest.java @@ -138,7 +138,7 @@ public class DistinguishedNameTest extends TestCase { assertEquals("Append failed", "ou=foo,ou=bar,cn=fie,ou=baz", path1.toString()); } - + public void testEquals() throws Exception { // original object @@ -581,4 +581,19 @@ public class DistinguishedNameTest extends TestCase { System.setProperty(DistinguishedName.SPACED_DN_FORMAT_PROPERTY, ""); } } + + public void testPreserveKeyCasePropertyTrueShouldNotEqualLowerCasedKeys() throws Exception { + try { + DistinguishedName name = new DistinguishedName("ou=foo,Ou=bar,oU=baz,OU=bim"); + // First check the default + assertEquals("ou=foo,ou=bar,ou=baz,ou=bim", name.toString()); + System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, "true"); + name = new DistinguishedName("ou=foo,Ou=bar,oU=baz,OU=bim"); + assertEquals("ou=foo,Ou=bar,oU=baz,OU=bim", name.toString()); + } + finally { + // Always restore the system setting + System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, ""); + } + } } diff --git a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java index 477927b3..5aa4af33 100644 --- a/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java +++ b/test/integration-tests/src/test/java/org/springframework/ldap/LdapTemplateModifyITest.java @@ -159,6 +159,40 @@ public class LdapTemplateModifyITest extends AbstractLdapTemplateIntegrationTest } } + // LDAP-188 + @Test + public void testModifyAttributes_AddAttributeValueAsDistinguishedName() { + try { + // prepare test data + String dn = "cn=ROLE_USER,ou=groups"; + String lowerCasedName = "cn=Some Person,ou=company1,c=Sweden,dc=jayway,dc=se"; + String upperCasedName = "CN=Some Person,OU=company1,C=Sweden,DC=jayway,DC=se"; + DirContextOperations ctx = tested.lookupContext(dn); + ctx.removeAttributeValue("uniqueMember", lowerCasedName); + ctx.addAttributeValue("uniqueMember", upperCasedName); + tested.modifyAttributes(ctx); + + // without this, the member added above will not be removed and the test fails + System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, Boolean.TRUE.toString()); + + ctx = tested.lookupContext(dn); + ctx.removeAttributeValue("uniqueMember", new DistinguishedName(upperCasedName).toCompactString()); + tested.modifyAttributes(ctx); + + // verify + DirContextAdapter result = (DirContextAdapter) tested.lookup(dn); + String[] attributes = result.getStringAttributes("uniqueMember"); + assertEquals(4, attributes.length); + assertEquals("0", "cn=Some Person2,ou=company1,c=Sweden,dc=jayway,dc=se", attributes[0]); + assertEquals("1", "cn=Some Person,ou=company1,c=Norway,dc=jayway,dc=se", attributes[1]); + assertEquals("2", "cn=Some Person,ou=company2,c=Sweden,dc=jayway,dc=se", attributes[2]); + assertEquals("3", "cn=Some Person3,ou=company1,c=Sweden,dc=jayway,dc=se", attributes[3]); + } + finally { + System.setProperty(DistinguishedName.PRESERVE_KEY_CASE_PROPERTY, ""); + } + } + /** * Test written originally to verify that duplicates are allowed on ordered * attributes, but had to be changed since Apache DS seems to disallow