/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2013-2015 ForgeRock AS */ package org.forgerock.opendj.adapter.server3x; import static org.assertj.core.api.Assertions.*; import static org.forgerock.opendj.ldap.LDAPConnectionFactory.AUTHN_BIND_REQUEST; import static org.forgerock.opendj.ldap.requests.Requests.newSimpleBindRequest; import java.security.GeneralSecurityException; import java.util.NoSuchElementException; import org.forgerock.opendj.ldap.AuthenticationException; import org.forgerock.opendj.ldap.AuthorizationException; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.Connections; import org.forgerock.opendj.ldap.ConstraintViolationException; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.DecodeOptions; import org.forgerock.opendj.ldap.Entries; import org.forgerock.opendj.ldap.Entry; import org.forgerock.opendj.ldap.EntryNotFoundException; import org.forgerock.opendj.ldap.LDAPConnectionFactory; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.LinkedHashMapEntry; import org.forgerock.opendj.ldap.ModificationType; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchResultReferenceIOException; import org.forgerock.opendj.ldap.SearchScope; import org.forgerock.opendj.ldap.controls.ADNotificationRequestControl; import org.forgerock.opendj.ldap.controls.GenericControl; import org.forgerock.opendj.ldap.controls.MatchedValuesRequestControl; import org.forgerock.opendj.ldap.controls.PermissiveModifyRequestControl; import org.forgerock.opendj.ldap.controls.PreReadRequestControl; import org.forgerock.opendj.ldap.controls.PreReadResponseControl; import org.forgerock.opendj.ldap.controls.SubentriesRequestControl; import org.forgerock.opendj.ldap.requests.AddRequest; import org.forgerock.opendj.ldap.requests.CompareRequest; import org.forgerock.opendj.ldap.requests.DeleteRequest; import org.forgerock.opendj.ldap.requests.ModifyDNRequest; import org.forgerock.opendj.ldap.requests.ModifyRequest; import org.forgerock.opendj.ldap.requests.PlainSASLBindRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.requests.SearchRequest; import org.forgerock.opendj.ldap.requests.WhoAmIExtendedRequest; import org.forgerock.opendj.ldap.responses.BindResult; import org.forgerock.opendj.ldap.responses.CompareResult; import org.forgerock.opendj.ldap.responses.Result; import org.forgerock.opendj.ldap.responses.SearchResultEntry; import org.forgerock.opendj.ldap.responses.WhoAmIExtendedResult; import org.forgerock.opendj.ldif.ConnectionEntryReader; import org.forgerock.util.Options; import org.opends.server.DirectoryServerTestCase; import org.opends.server.TestCaseUtils; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * This class defines a set of tests for the Adapters.class. */ @SuppressWarnings("javadoc") @Test(sequential=true) public class AdaptersTestCase extends DirectoryServerTestCase { private static final String USER_0_DN_STRING = "uid=user.0,o=test"; /** * Provides an anonymous connection factories. * * @return Anonymous connection factories. */ @DataProvider public Object[][] anonymousConnectionFactories() { return new Object[][] { { new LDAPConnectionFactory("localhost", getServerLdapPort()) }, { Adapters.newAnonymousConnectionFactory() } }; } private Integer getServerLdapPort() { return TestCaseUtils.getServerLdapPort(); } /** * Provides root connection factories. * * @return Root connection factories. */ @DataProvider public Object[][] rootConnectionFactories() { return new Object[][] { { new LDAPConnectionFactory("localhost", getServerLdapPort(), Options.defaultOptions() .set(AUTHN_BIND_REQUEST, newSimpleBindRequest("cn=directory manager", "password".toCharArray()))) }, { Adapters.newConnectionFactoryForUser(DN.valueOf("cn=directory manager")) } }; } /** * Launched before the tests, this function starts the server and adds data. * * @throws Exception * If the server could not be initialized. */ @BeforeClass public void startServer() throws Exception { TestCaseUtils.startServer(); // Creates a root connection to add data final Connection connection = Adapters.newRootConnection(); // @formatter:off connection.add( "dn: uid=user.0, o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "cn: Aaccf Amar", "sn:user.0", "uid:user.0", "description: This is the description for Aaccf Amar.", "userPassword:: cGFzc3dvcmQ=", "postalAddress: Aaccf Amar$01251 Chestnut Street$Panama City, DE 50369", "postalCode: 50369"); connection.add( "dn: uid=user.1, o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "cn: Aaren Atp", "sn:user.1", "uid:user.1", "description: This is the description for Aaren Atp.", "postalAddress: Aaren Atp$70110 Fourth Street$New Haven, OH 93694", "postalCode: 93694"); connection.add( "dn: uid=user.2, o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "cn: Aarika Atpco", "sn: user.2", "uid:user.2", "description: This is the description for Aarika Atpco.", "userPassword:: cGFzc3dvcmQ=", "postalAddress: Aarika Atpco$00900 Maple Street$New Orleans, KS 10857", "postalCode: 10857"); connection.add( "dn: uid=user.3, o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "cn: Aaron Atrc", "sn:user.3", "uid:user.3", "description: This is the description for Aaron Atrc.", "postalAddress: Aaron Atrc$59748 Willow Street$Green Bay, TN 66239", "postalCode: 66239"); connection.add( "dn: uid=user.4, o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "cn: Samantha Carter", "sn: Carter", "uid:user.4", "description: This is the description for Samantha Carter.", "postalAddress: 59748 Willow Street$Green Bay, TN 66000", "postalCode: 66000"); // @formatter:on connection.close(); } /** * Clean up data at the end of tests. */ @AfterClass public void shutDownEmbeddedServerServer() throws Exception { // Delete all added entries but user.3 which is already removed in one test for (int i = 0; i < 5; i++) { if (i != 3) { TestCaseUtils.deleteEntry(org.opends.server.types.DN.valueOf("uid=user." + i + ", o=test")); } } } /** * A simple LDAP connection. * * @throws LdapException */ @Test public void testSimpleLDAPConnectionFactorySimpleBind() throws LdapException { final LDAPConnectionFactory factory = new LDAPConnectionFactory("localhost", getServerLdapPort()); Connection connection = null; try { connection = factory.getConnection(); connection.bind("cn=Directory Manager", "password".toCharArray()); assertThat(connection.isValid()).isTrue(); assertThat(connection.isClosed()).isFalse(); } finally { if (connection != null) { connection.close(); } } } /** * Tests a SASL Bind with an LDAP connection. * * @throws NumberFormatException * @throws GeneralSecurityException * @throws LdapException */ @Test public void testLDAPSASLBind() throws NumberFormatException, GeneralSecurityException, LdapException { LDAPConnectionFactory factory = new LDAPConnectionFactory("localhost", getServerLdapPort()); Connection connection = factory.getConnection(); PlainSASLBindRequest request = Requests.newPlainSASLBindRequest("u:user.0", "password".toCharArray()); try { connection.bind(request); } finally { if (connection != null) { connection.close(); } } } /** * Tests an SASL connection with the adapter. * * @throws LdapException */ @Test public void testAdapterConnectionSASLBindRequest() throws LdapException, GeneralSecurityException { final Connection connection = Adapters.newRootConnection(); PlainSASLBindRequest request = Requests.newPlainSASLBindRequest("u:user.0", "password".toCharArray()); try { connection.bind(request); } finally { if (connection != null) { connection.close(); } } } /** * This type of connection is not supported. Anonymous SASL Mechanisms is * disabled in the config.ldif file. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = LdapException.class) public void testConnectionAnonymousSASLBindRequest(final ConnectionFactory factory) throws LdapException { final Connection connection = factory.getConnection(); try { connection.bind(Requests.newAnonymousSASLBindRequest("anonymousSASLBindRequest")); } finally { connection.close(); } } /** * Binds as a root. * * @throws Exception */ @Test public void testAdapterConnectionSimpleBindAsRoot() throws Exception { final Connection connection = Adapters.newRootConnection(); final BindResult result = connection.bind("cn=Directory Manager", "password".toCharArray()); assertThat(connection.isValid()).isTrue(); assertThat(result.getResultCode()).isEqualTo(ResultCode.SUCCESS); connection.close(); } /** * Binds as a known user. * * @throws Exception */ @Test public void testAdapterConnectionSimpleBindAsAUser() throws Exception { final Connection connection = Adapters.newConnectionForUser(DN.valueOf(USER_0_DN_STRING)); final BindResult result = connection.bind(USER_0_DN_STRING, "password".toCharArray()); assertThat(result.getResultCode()).isEqualTo(ResultCode.SUCCESS); connection.close(); } /** * Binds as a known user but using the wrong password. * * @throws Exception */ @Test(expectedExceptions = AuthenticationException.class) public void testAdapterConnectionSimpleBindAsAUserWrongPassword() throws Exception { final Connection connection = Adapters.newConnectionForUser(DN.valueOf(USER_0_DN_STRING)); try { // Invalid credentials connection.bind(USER_0_DN_STRING, "pass".toCharArray()); } finally { connection.close(); } } /** * Tries to bind as anonymous. * * @throws Exception */ @Test public void testAdapterConnectionSimpleBind() throws Exception { // Anonymous final Connection connection = Adapters.newAnonymousConnection(); final BindResult result = connection.bind("", "".toCharArray()); assertThat(result.getDiagnosticMessage()).isEmpty(); connection.close(); } /** * Testing the adapters with a simple add request. * * @throws Exception */ @Test public void testAdapterAddRequest() throws Exception { final Connection connection = Adapters.newRootConnection(); // @formatter:off final AddRequest addRequest = Requests.newAddRequest( "dn: sn=carter,o=test", "objectClass: top", "objectClass: person", "cn: scarter"); // @formatter:on final Result r = connection.add(addRequest); assertThat(r.getDiagnosticMessage()).isEmpty(); assertThat(r.isSuccess()).isTrue(); // We find the added entry : final SearchResultEntry srEntry = connection.searchSingleEntry(Requests.newSearchRequest( "sn=carter,o=test", SearchScope.BASE_OBJECT, "(cn=scarter)")); assertThat(srEntry.getName().toString()).isEqualTo("sn=carter,o=test"); connection.close(); } /** * Tries an add request but the entry already exists. * * @throws Exception */ @Test(dataProvider = "rootConnectionFactories", expectedExceptions = ConstraintViolationException.class) public void testAdapterAddRequestFails(final ConnectionFactory factory) throws Exception { final Connection connection = factory.getConnection(); // @formatter:off final AddRequest addRequest = Requests.newAddRequest( "dn: sn=bjensen,o=test", "objectClass: top", "objectClass: person", "cn: bjensen"); // @formatter:on // First add : Result r = connection.add(addRequest); assertThat(r.getDiagnosticMessage()).isEmpty(); assertThat(r.isSuccess()).isTrue(); // Second : try { r = connection.add(addRequest); } finally { connection.close(); } } /** * Uses the adapter to perform a search request. * * @throws Exception */ @Test public void testAdapterSearchRequest() throws Exception { final Connection connection = Adapters.newRootConnection(); final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(sn=user.1)"); // Performs the search : final ConnectionEntryReader reader = connection.search(request); assertThat(reader.isEntry()).isTrue(); final SearchResultEntry srEntry = reader.readEntry(); assertThat(srEntry).isNotNull(); Entry expectedEntry = new LinkedHashMapEntry("dn: uid=user.1,o=test", "objectClass: top", "objectClass: person", "objectClass: inetOrgPerson", "objectClass: organizationalPerson", "sn:user.1", "uid:user.1", "cn: Aaren Atp", "description: This is the description for Aaren Atp.", "postalAddress: Aaren Atp$70110 Fourth Street$New Haven, OH 93694", "postalCode: 93694"); Entry original = new LinkedHashMapEntry(srEntry); // No differences expected. assertThat(Entries.diffEntries(original, expectedEntry).getModifications()).isEmpty(); assertThat(srEntry.getName().toString()).isEqualTo("uid=user.1,o=test"); assertThat(srEntry.getAttributeCount()).isEqualTo(7); assertThat(srEntry.getAttribute("description").firstValueAsString()).isEqualTo( "This is the description for Aaren Atp."); assertThat(srEntry.getAttribute("postalAddress").firstValueAsString()).isEqualTo( "Aaren Atp$70110 Fourth Street$New Haven, OH 93694"); assertThat(srEntry.getAttribute("postalCode").firstValueAsString()).isEqualTo("93694"); // top - person - inetOrgPerson - organizationalPerson. assertThat(srEntry.getAttribute("objectClass").toArray().length).isEqualTo(4); assertThat(reader.hasNext()).isFalse(); connection.close(); } /** * Tries to perform a search with the adapter. No result expected. * * @throws Exception */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterSearchRequestWithNoResults(final ConnectionFactory factory) throws Exception { final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(uid=unknown)").addControl( MatchedValuesRequestControl.newControl(true, "(uid=user.1)")); final Connection connection = factory.getConnection(); ConnectionEntryReader reader = connection.search(request); assertThat(reader.hasNext()).isFalse(); connection.close(); } /** * Tries to perform a search single entry. Exception expected. * * @param factory * The connection factory. * @throws Exception */ @Test(dataProvider = "rootConnectionFactories", expectedExceptions = EntryNotFoundException.class) public void testAdapterSearchSingleEntryWithNoResults(final ConnectionFactory factory) throws Exception { final Connection connection = factory.getConnection(); try { connection.searchSingleEntry(Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(uid=unknown)")); } finally { connection.close(); } } /** * Performs a search with a sub entries request control. Sub-entries are * included and the normal entries are excluded. No result expected. * * @throws LdapException * @throws SearchResultReferenceIOException */ @Test(dataProvider = "rootConnectionFactories", expectedExceptions = NoSuchElementException.class) public void testAdapterSearchRequestSubEntriesWithNoResult(final ConnectionFactory factory) throws LdapException, SearchResultReferenceIOException { final Connection connection = factory.getConnection(); try { final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "cn=*", "cn", "subtreeSpecification") // sub-entries included, normal entries excluded. .addControl(SubentriesRequestControl.newControl(true, true)); final ConnectionEntryReader reader = connection.search(request); assertThat(reader.isEntry()).isFalse(); assertThat(reader.isReference()).isFalse(); reader.readEntry(); } finally { connection.close(); } } /** * Performs a search with a sub entries request control. Sub-entries are * excluded this time and the normal entries are included. * * @throws LdapException * @throws SearchResultReferenceIOException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterSearchRequestSubEntries(final ConnectionFactory factory) throws LdapException, SearchResultReferenceIOException { final Connection connection = factory.getConnection(); final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "cn=*", "cn", "subtreeSpecification") // sub-entries excluded, normal entries included. .addControl(SubentriesRequestControl.newControl(true, false)); final ConnectionEntryReader reader = connection.search(request); assertThat(reader.isEntry()).isTrue(); // All the entries are present. int nbEntries = 0; while (reader.hasNext()) { final SearchResultEntry entry = reader.readEntry(); assertThat(entry).isNotNull(); nbEntries++; } // All the entries must appear (except those which were deleted by another operation/test). assertThat(nbEntries >= 3); connection.close(); } /** * Deletes an inexistent entry. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories", expectedExceptions = EntryNotFoundException.class) public void testAdapterDeleteRequestNoSuchEntry(final ConnectionFactory factory) throws LdapException { final DeleteRequest deleteRequest = Requests.newDeleteRequest("cn=test"); final Connection connection = factory.getConnection(); try { connection.delete(deleteRequest); } finally { connection.close(); } } /** * Deletes an existing entry with the 'no-op' control. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterDeleteRequestNoOpControl(final ConnectionFactory factory) throws LdapException { final DeleteRequest deleteRequest = Requests.newDeleteRequest("uid=user.1, o=test") // The no-op control is specified with his OID. .addControl(GenericControl.newControl("1.3.6.1.4.1.4203.1.10.2")); final Connection connection = factory.getConnection(); final Result result = connection.delete(deleteRequest); assertThat(result.getResultCode()).isEqualTo(ResultCode.NO_OPERATION); // Verifies that the delete has no impact in this case (due to no_operation control) final SearchResultEntry srEntry = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.1, o=test", SearchScope.BASE_OBJECT, "(uid=user.1)")); assertThat(srEntry).isNotNull(); assertThat(srEntry.getName().toString()).isEqualTo("uid=user.1,o=test"); connection.close(); } /** * Deletes an existing entry. * * @throws LdapException */ @Test public void testAdapterDeleteRequest() throws LdapException { final Connection connection = Adapters.newRootConnection(); // Checks if the entry exists. SearchResultEntry sre = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.3, o=test", SearchScope.BASE_OBJECT, "(uid=user.3)")); assertThat(sre).isNotNull(); final DeleteRequest deleteRequest = Requests.newDeleteRequest("uid=user.3, o=test"); connection.delete(deleteRequest); // Verifies if the entry was correctly deleted. try { connection.searchSingleEntry(Requests.newSearchRequest("uid=user.3, o=test", SearchScope.BASE_OBJECT, "(uid=user.3)")); fail("Expected EntryNotFoundException to be thrown"); } catch (EntryNotFoundException ex) { // Expected - no result. } finally { connection.close(); } } /** * Modifies an existing entry. * * @throws LdapException * @throws DecodeException */ @Test public void testAdapterModifyRequest() throws LdapException, DecodeException { final ModifyRequest changeRequest = Requests.newModifyRequest("uid=user.2, o=test").addControl( PreReadRequestControl.newControl(true, "mail")).addModification( ModificationType.ADD, "mail", "modified@example.com"); final Connection connection = Adapters.newRootConnection(); final Result result = connection.modify(changeRequest); assertThat(result.getDiagnosticMessage()).isEmpty(); assertThat(result.getControls()).isNotEmpty(); assertThat(result.getControls().get(0).getOID()).isEqualTo("1.3.6.1.1.13.1"); // pre read control OID. assertThat(result.getControls().get(0).isCritical()).isFalse(); // pre read response control. assertThat(result.getMatchedDN()).isEmpty(); PreReadResponseControl control = result.getControl(PreReadResponseControl.DECODER, new DecodeOptions()); // Pre read control sends a copy of the target entry exactly as it was // immediately before the processing for that operation - mail attribute doesn't exist. Entry unmodifiedEntry = control.getEntry(); assertThat(unmodifiedEntry.getAttribute("mail")).isNull(); //Verifies that entry has been correctly modified. final SearchResultEntry srEntry = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.2, o=test", SearchScope.BASE_OBJECT, "(uid=user.2)")); assertThat(srEntry.getAttribute("mail").firstValueAsString()).isEqualTo( "modified@example.com"); } /** * Tries to modify the existing entry with the same values but using the * permissive modify control. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterUsePermissiveModifyRequest(final ConnectionFactory factory) throws LdapException { final ModifyRequest changeRequest = Requests.newModifyRequest("uid=user.2, o=test").addControl( PermissiveModifyRequestControl.newControl(true)).addModification( ModificationType.ADD, "uid", "user.2"); final Connection connection = factory.getConnection(); connection.modify(changeRequest); // Verifies that entry has been correctly modified. final SearchResultEntry srEntry = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.2, o=test", SearchScope.BASE_OBJECT, "(uid=user.2)")); assertThat(srEntry.getAttribute("uid").firstValueAsString()).isEqualTo("user.2"); } /** * Tries to modify the existing entry with the same values. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories", expectedExceptions = ConstraintViolationException.class) public void testAdapterModifyRequestFails(final ConnectionFactory factory) throws LdapException { final ModifyRequest changeRequest = Requests.newModifyRequest("uid=user.2, o=test").addModification( ModificationType.ADD, "uid", "user.2"); final Connection connection = factory.getConnection(); connection.modify(changeRequest); } /** * Modifies the DN. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterModifyDNRequest(final ConnectionFactory factory) throws LdapException { final Connection connection = factory.getConnection(); // Verifies that entry has been correctly modified. final SearchResultEntry srEntryExists = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.4, o=test", SearchScope.BASE_OBJECT, "(uid=user.4)")); assertThat(srEntryExists).isNotNull(); // Modifying the DN. ModifyDNRequest changeRequest = Requests.newModifyDNRequest("uid=user.4,o=test", "uid=user.test") .setDeleteOldRDN(true); connection.modifyDN(changeRequest); // Checks previous mod. final SearchResultEntry srEntry = connection.searchSingleEntry(Requests.newSearchRequest( "uid=user.test, o=test", SearchScope.BASE_OBJECT, "(uid=user.test)")); assertThat(srEntry).isNotNull(); // Modify again the DN as previously. changeRequest = Requests.newModifyDNRequest("uid=user.test,o=test", "uid=user.4") .setDeleteOldRDN(true); connection.modifyDN(changeRequest); } /** * Compare request. The comparison returns true. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterCompareRequestTrue(final ConnectionFactory factory) throws LdapException { final CompareRequest compareRequest = Requests.newCompareRequest(USER_0_DN_STRING, "uid", "user.0"); final Connection connection = factory.getConnection(); final CompareResult result = connection.compare(compareRequest); assertThat(result.getResultCode()).isEqualTo(ResultCode.COMPARE_TRUE); assertThat(result.getDiagnosticMessage()).isEmpty(); assertThat(result.getControls()).isEmpty(); assertThat(result.getMatchedDN()).isEmpty(); } /** * Compare request. The comparison returns false. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterCompareRequestFalse(final ConnectionFactory factory) throws LdapException { final CompareRequest compareRequest = Requests.newCompareRequest(USER_0_DN_STRING, "uid", "scarter"); final Connection connection = factory.getConnection(); final CompareResult result = connection.compare(compareRequest); assertThat(result.getResultCode()).isEqualTo(ResultCode.COMPARE_FALSE); assertThat(result.getDiagnosticMessage()).isEmpty(); assertThat(result.getControls()).isEmpty(); assertThat(result.getMatchedDN()).isEmpty(); } /** * Use the Who Am I? extended request. * * @throws LdapException */ @Test(dataProvider = "rootConnectionFactories") public void testAdapterExtendedOperation(final ConnectionFactory factory) throws LdapException { final WhoAmIExtendedRequest request = Requests.newWhoAmIExtendedRequest(); final Connection connection = factory.getConnection(); try { final WhoAmIExtendedResult extResult = connection.extendedRequest(request); assertThat(extResult.getAuthorizationID()).isNotEmpty(); } finally { connection.close(); } } /** * If an anonymous tries to delete, sends a result code : insufficient * access rights. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = AuthorizationException.class) public void testAdapterAsAnonymousCannotPerformDeleteRequest(final ConnectionFactory factory) throws LdapException { final DeleteRequest deleteRequest = Requests.newDeleteRequest("uid=user.2,o=test"); final Connection connection = factory.getConnection(); try { connection.delete(deleteRequest); } finally { connection.close(); } } /** * If an anonymous tries to do an add request, sends a result code : * insufficient access rights. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = AuthorizationException.class) public void testAdapterAsAnonymousCannotPerformAddRequest(final ConnectionFactory factory) throws LdapException { // @formatter:off final AddRequest addRequest = Requests.newAddRequest( "dn: sn=scarter,o=test", "objectClass: top", "objectClass: person", "cn: scarter"); // @formatter:on final Connection connection = factory.getConnection(); try { connection.add(addRequest); } finally { connection.close(); } } /** * If an anonymous tries to do a modify DN request, sends a result code : * insufficient access rights. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = AuthorizationException.class) public void testAdapterAsAnonymousCannotPerformModifyDNRequest(final ConnectionFactory factory) throws LdapException { final Connection connection = factory.getConnection(); final ModifyDNRequest changeRequest = Requests.newModifyDNRequest("uid=user.2,o=test", "uid=user.test") .setDeleteOldRDN(true); try { connection.modifyDN(changeRequest); } finally { connection.close(); } } /** * If an anonymous tries to do a modify request, sends a result code : * insufficient access rights. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = LdapException.class) public void testAdapterAsAnonymousCannotPerformModifyRequest(final ConnectionFactory factory) throws LdapException { final ModifyRequest changeRequest = Requests.newModifyRequest("uid=user.2,o=test").addControl( PreReadRequestControl.newControl(true, "mail")).addModification( ModificationType.REPLACE, "mail", "modified@example.com"); final Connection connection = factory.getConnection(); try { connection.modify(changeRequest); } finally { connection.close(); } } /** * The anonymous connection is allowed to perform compare request. * * @throws LdapException */ @Test(dataProvider = "anonymousConnectionFactories") public void testAdapterAsAnonymousPerformsCompareRequest(final ConnectionFactory factory) throws LdapException { final CompareRequest compareRequest = Requests.newCompareRequest(USER_0_DN_STRING, "uid", "user.0"); final Connection connection = factory.getConnection(); final CompareResult result = connection.compare(compareRequest); assertThat(result.getResultCode()).isEqualTo(ResultCode.COMPARE_TRUE); assertThat(result.getDiagnosticMessage()).isEmpty(); assertThat(result.getControls()).isEmpty(); assertThat(result.getMatchedDN()).isEmpty(); connection.close(); } /** * The anonymous connection is allowed to perform search request. * * @throws Exception */ @Test(dataProvider = "anonymousConnectionFactories") public void testAdapterAsAnonymousPerformsSearchRequest(final ConnectionFactory factory) throws Exception { final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(uid=user.1)"); final Connection connection = factory.getConnection(); final ConnectionEntryReader reader = connection.search(request); assertThat(reader.isEntry()).isTrue(); final SearchResultEntry entry = reader.readEntry(); assertThat(entry).isNotNull(); assertThat(entry.getName().toString()).isEqualTo("uid=user.1,o=test"); assertThat(reader.hasNext()).isFalse(); } /** * The anonymous connection is not allowed to perform search request * associated with a control. * <p> * Unavailable Critical Extension: The request control with Object * Identifier (OID) "x.x.x" cannot be used due to insufficient access * rights. * * @throws Exception */ @Test(dataProvider = "anonymousConnectionFactories", expectedExceptions = LdapException.class) public void testAdapterAsAnonymousCannotPerformSearchRequestWithControl( final ConnectionFactory factory) throws Exception { final Connection connection = factory.getConnection(); final SearchRequest request = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(uid=user.1)").addControl(ADNotificationRequestControl.newControl(true)); final ConnectionEntryReader reader = connection.search(request); reader.readEntry(); } /** * Creates an LDAP Connection and performs some basic calls like * add/delete/search and compare results with an SDK adapter connection * doing the same. * * @throws LdapException * @throws SearchResultReferenceIOException */ @Test public void testLDAPConnectionAndAdapterComparison() throws LdapException, SearchResultReferenceIOException { // @formatter:off final AddRequest addRequest = Requests.newAddRequest( "dn: sn=babs,o=test", "objectClass: top", "objectClass: person", "cn: bjensen"); // @formatter:on final SearchRequest searchRequest = Requests.newSearchRequest("o=test", SearchScope.WHOLE_SUBTREE, "(uid=user.*)").addControl( MatchedValuesRequestControl.newControl(true, "(uid=user.1)")); final DeleteRequest deleteRequest = Requests.newDeleteRequest("sn=babs,o=test"); // LDAP Connection final LDAPConnectionFactory factory = new LDAPConnectionFactory("localhost", getServerLdapPort()); Connection connection = null; connection = factory.getConnection(); connection.bind("cn=Directory Manager", "password".toCharArray()); assertThat(connection.isValid()).isTrue(); final Result addResult = connection.add(addRequest); assertThat(addResult.getResultCode()).isEqualTo(ResultCode.SUCCESS); final ConnectionEntryReader reader = connection.search(searchRequest); final Result deleteResult = connection.delete(deleteRequest); assertThat(deleteResult.getResultCode()).isEqualTo(ResultCode.SUCCESS); // SDK Adapter connection final Connection adapterConnection = Adapters.newRootConnection(); final Result sdkAddResult = adapterConnection.add(addRequest); final ConnectionEntryReader sdkReader = adapterConnection.search(searchRequest); final Result sdkDeleteResult = adapterConnection.delete(deleteRequest); // Compare the results : // AddRequest assertThat(addResult.getMatchedDN()).isEqualTo(sdkAddResult.getMatchedDN()); assertThat(addResult.getControls()).isEqualTo(sdkAddResult.getControls()); assertThat(addResult.getDiagnosticMessage()).isEqualTo(sdkAddResult.getDiagnosticMessage()); assertThat(addResult.getReferralURIs()).isEqualTo(sdkAddResult.getReferralURIs()); // DeleteRequest assertThat(deleteResult.getMatchedDN()).isEqualTo(sdkDeleteResult.getMatchedDN()); assertThat(deleteResult.getControls()).isEqualTo(sdkDeleteResult.getControls()); assertThat(deleteResult.getDiagnosticMessage()).isEqualTo( sdkDeleteResult.getDiagnosticMessage()); assertThat(deleteResult.getReferralURIs()).isEqualTo(sdkDeleteResult.getReferralURIs()); // ConnectionEntryReader while (reader.hasNext()) { SearchResultEntry entry = reader.readEntry(); SearchResultEntry sdkEntry = sdkReader.readEntry(); assertThat(entry.getName().toString()).isEqualTo(sdkEntry.getName().toString()); assertThat(entry.getAttributeCount()).isEqualTo(sdkEntry.getAttributeCount()); assertThat(entry.getAllAttributes().iterator().next().getAttributeDescription()) .isEqualTo(sdkEntry.getAllAttributes().iterator().next().getAttributeDescription()); assertThat(entry.getControls().size()).isEqualTo(sdkEntry.getControls().size()); } } }