Added rebind with DirContextOperations (LDAP-144).

This commit is contained in:
Ulrik Sandberg
2008-11-20 17:15:11 +00:00
parent 55432d45f2
commit bde0b6f186
4 changed files with 127 additions and 24 deletions

View File

@@ -26,7 +26,6 @@ import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.ContextNotEmptyException;
import org.springframework.ldap.NamingException;
import org.springframework.ldap.core.support.AbstractContextSource;
@@ -1261,7 +1260,7 @@ public interface LdapOperations {
/**
* Bind the data in the supplied context in the tree. All specified
* Attributes in will be bound to the DN set on the instance.
* attributes <code>ctx</code>in will be bound to the DN set on <code>ctx</code>.
* <p>
* Example:<br>
*
@@ -1280,6 +1279,29 @@ public interface LdapOperations {
*/
void bind(DirContextOperations ctx);
/**
* Remove an entry and replace it with a new one. The attributes used to
* create the entry are retrieved from the <code>ctx</code> parameter. This
* method assumes that the specified context already exists - if not it will
* fail. The entry will be bound to the DN set on <code>ctx</code>.
* <p>
* Example:<br>
*
* <pre>
* DirContextOperations ctx = new DirContextAdapter(dn);
* ctx.setAttributeValue(&quot;cn&quot;, &quot;john doe&quot;);
* ctx.setAttributeValue(&quot;description&quot;, &quot;some description&quot;);
* //More initialization here.
*
* ldapTemplate.rebind(ctx);
* </pre>
* @param ctx the context to rebind
* @throws IllegalStateException if no DN is set or if the instance is in
* update mode.
* @since 1.3
*/
void rebind(DirContextOperations ctx);
/**
* Utility method to perform a simple LDAP 'bind' authentication. Search for
* the LDAP entry to authenticate using the supplied base DN and filter; use

View File

@@ -1337,7 +1337,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
/*
* (non-Javadoc)
*
* @seeorg.springframework.ldap.core.simple.SimpleLdapOperations#bind(org.
* @seeorg.springframework.ldap.core.LdapOperations#bind(org.
* springframework.ldap.core.DirContextOperations)
*/
public void bind(DirContextOperations ctx) {
@@ -1350,6 +1350,23 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
}
}
/*
* @see
* org.springframework.ldap.core.LdapOperations#rebind(org.springframework.
* ldap.core.DirContextOperations)
*/
public void rebind(DirContextOperations ctx) {
Name dn = ctx.getDn();
if (dn != null && !ctx.isUpdateMode()) {
rebind(dn, ctx, null);
}
else {
throw new IllegalStateException(
"The DirContextOperations instance needs to be properly initialized.");
}
}
/*
* (non-Javadoc)
*

View File

@@ -39,6 +39,12 @@ import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.PartialResultException;
import org.springframework.ldap.UncategorizedLdapException;
/**
* Unit tests for the LdapTemplate class.
*
* @author Mattias Hellborg Arthursson
* @author Ulrik Sandberg
*/
public class LdapTemplateTest extends TestCase {
private static final String DEFAULT_BASE_STRING = "o=example.com";
@@ -168,7 +174,6 @@ public class LdapTemplateTest extends TestCase {
dirContextOperationsConrol = null;
dirContextOperationsMock = null;
}
protected void replay() {
@@ -1118,7 +1123,6 @@ public class LdapTemplateTest extends TestCase {
tested.bind(nameMock, expectedObject, expectedAttributes);
verify();
}
public void testBind_String() throws Exception {
@@ -1134,7 +1138,6 @@ public class LdapTemplateTest extends TestCase {
tested.bind(DEFAULT_BASE_STRING, expectedObject, expectedAttributes);
verify();
}
public void testBind_NamingException() throws Exception {
@@ -1158,7 +1161,23 @@ public class LdapTemplateTest extends TestCase {
}
verify();
}
public void testBindWithContext() throws Exception {
expectGetReadWriteContext();
dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock
.getDn(), nameMock);
dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock
.isUpdateMode(), false);
dirContextMock.bind(nameMock, dirContextOperationsMock, null);
dirContextMock.close();
replay();
tested.bind(dirContextOperationsMock);
verify();
}
public void testUnbind() throws Exception {
@@ -1184,6 +1203,23 @@ public class LdapTemplateTest extends TestCase {
verify();
}
public void testRebindWithContext() throws Exception {
expectGetReadWriteContext();
dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock
.getDn(), nameMock);
dirContextOperationsConrol.expectAndReturn(dirContextOperationsMock
.isUpdateMode(), false);
dirContextMock.rebind(nameMock, dirContextOperationsMock, null);
dirContextMock.close();
replay();
tested.rebind(dirContextOperationsMock);
verify();
}
public void testUnbindRecursive() throws Exception {
expectGetReadWriteContext();
@@ -1864,16 +1900,17 @@ public class LdapTemplateTest extends TestCase {
assertFalse(result);
}
/**
* Needed to verify search control values.
*
* @author Mattias Hellborg Arthursson
*/
private static class SearchControlsMatcher extends AbstractMatcher {
protected boolean argumentMatches(Object arg0, Object arg1) {
if (arg0 instanceof SearchControls && arg1 instanceof SearchControls) {
SearchControls s0 = (SearchControls) arg0;
SearchControls s1 = (SearchControls) arg1;
protected boolean argumentMatches(Object expected, Object actual) {
if (expected instanceof SearchControls && actual instanceof SearchControls) {
SearchControls s0 = (SearchControls) expected;
SearchControls s1 = (SearchControls) actual;
return s0.getSearchScope() == s1.getSearchScope()
&& s0.getReturningObjFlag() == s1.getReturningObjFlag()
@@ -1882,7 +1919,7 @@ public class LdapTemplateTest extends TestCase {
&& s0.getReturningAttributes() == s1.getReturningAttributes();
}
else {
return super.argumentMatches(arg0, arg1);
return super.argumentMatches(expected, actual);
}
}
}

View File

@@ -36,21 +36,20 @@ import org.springframework.test.context.ContextConfiguration;
* class tests a little too much, but we need to clean up after binding, so the
* most efficient way to test is to do it all in one test method. Also, the
* methods in this class relies on that the lookup method works as it should -
* that should be ok, since that is verified in a separate test class. NOTE: if
* any of the tests in this class fails, it may be necessary to run the cleanup
* script as described in README.txt under /src/iutest/.
* that should be ok, since that is verified in a separate test class.
*
* @author Mattias Hellborg Arthursson
*/
@ContextConfiguration(locations = { "/conf/ldapTemplateTestContext.xml" })
public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegrationTest {
public class LdapTemplateBindUnbindITest extends
AbstractLdapTemplateIntegrationTest {
@Autowired
private LdapTemplate tested;
private static String DN = "cn=Some Person4,ou=company1,c=Sweden";
@Test
public void testBindAndUnbind_Attributes_Plain() {
public void testBindAndUnbindWithAttributes() {
Attributes attributes = setupAttributes();
tested.bind(DN, null, attributes);
verifyBoundCorrectData();
@@ -59,7 +58,7 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
}
@Test
public void testBindAndUnbind_Attributes_DIstinguishedName() {
public void testBindAndUnbindWithAttributesUsingDistinguishedName() {
Attributes attributes = setupAttributes();
tested.bind(new DistinguishedName(DN), null, attributes);
verifyBoundCorrectData();
@@ -68,9 +67,10 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
}
@Test
public void testBindAndUnbind_DirContextAdapter_Plain() {
public void testBindAndUnbindWithDirContextAdapter() {
DirContextAdapter adapter = new DirContextAdapter();
adapter.setAttributeValues("objectclass", new String[] { "top", "person" });
adapter.setAttributeValues("objectclass", new String[] { "top",
"person" });
adapter.setAttributeValue("cn", "Some Person4");
adapter.setAttributeValue("sn", "Person4");
@@ -81,9 +81,10 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
}
@Test
public void testBindAndUnbind_DirContextAdapter_DIstinguishedName() {
public void testBindAndUnbindWithDirContextAdapterUsingDistinguishedName() {
DirContextAdapter adapter = new DirContextAdapter();
adapter.setAttributeValues("objectclass", new String[] { "top", "person" });
adapter.setAttributeValues("objectclass", new String[] { "top",
"person" });
adapter.setAttributeValue("cn", "Some Person4");
adapter.setAttributeValue("sn", "Person4");
@@ -94,9 +95,11 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
}
@Test
public void testBindAndUnbindPlainDirContextAdapter() {
DirContextAdapter adapter = new DirContextAdapter(new DistinguishedName(DN));
adapter.setAttributeValues("objectclass", new String[] { "top", "person" });
public void testBindAndUnbindWithDirContextAdapterOnly() {
DirContextAdapter adapter = new DirContextAdapter(
new DistinguishedName(DN));
adapter.setAttributeValues("objectclass", new String[] { "top",
"person" });
adapter.setAttributeValue("cn", "Some Person4");
adapter.setAttributeValue("sn", "Person4");
@@ -106,6 +109,24 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
verifyCleanup();
}
@Test
public void testBindAndRebindWithDirContextAdapterOnly() {
DirContextAdapter adapter = new DirContextAdapter(
new DistinguishedName(DN));
adapter.setAttributeValues("objectclass", new String[] { "top",
"person" });
adapter.setAttributeValue("cn", "Some Person4");
adapter.setAttributeValue("sn", "Person4");
tested.bind(adapter);
verifyBoundCorrectData();
adapter.setAttributeValue("sn", "Person4.Changed");
tested.rebind(adapter);
verifyReboundCorrectData();
tested.unbind(DN);
verifyCleanup();
}
private Attributes setupAttributes() {
Attributes attributes = new BasicAttributes();
BasicAttribute ocattr = new BasicAttribute("objectclass");
@@ -123,6 +144,12 @@ public class LdapTemplateBindUnbindITest extends AbstractLdapTemplateIntegration
assertEquals("Person4", result.getStringAttribute("sn"));
}
private void verifyReboundCorrectData() {
DirContextAdapter result = (DirContextAdapter) tested.lookup(DN);
assertEquals("Some Person4", result.getStringAttribute("cn"));
assertEquals("Person4.Changed", result.getStringAttribute("sn"));
}
private void verifyCleanup() {
try {
tested.lookup(DN);