/** * Clear the directory sub-tree starting with the node represented by the supplied distinguished * name. * * @param ctx The DirContext to use for cleaning the tree. * @param name the distinguished name of the root node. * @throws NamingException if anything goes wrong removing the sub-tree. */ public static void clearSubContexts(DirContext ctx, Name name) throws NamingException { NamingEnumeration enumeration = null; try { enumeration = ctx.listBindings(name); while (enumeration.hasMore()) { Binding element = (Binding) enumeration.next(); Name childName = LdapUtils.newLdapName(element.getName()); childName = LdapUtils.prepend(childName, name); try { ctx.destroySubcontext(childName); } catch (ContextNotEmptyException e) { clearSubContexts(ctx, childName); ctx.destroySubcontext(childName); } } } catch (NamingException e) { e.printStackTrace(); } finally { try { enumeration.close(); } catch (Exception e) { // Never mind this } } }
/** * Construct a DirContextAdapter given the supplied paramters. The <code>name</code> is normally a * JNDI <code>CompositeName</code>, which needs to be handled with particuclar care. Specifically * the escaping of a <code>CompositeName</code> destroys proper escaping of Distinguished Names. * Also, the name might contain referral information, in which case we need to separate the server * information from the actual Distinguished Name so that we can create a representing * DirContextAdapter. * * @param attrs the attributes * @param name the Name, typically a <code>CompositeName</code>, possibly including referral * information. * @param nameInNamespace the Name in namespace. * @return a {@link DirContextAdapter} representing the specified information. */ DirContextAdapter constructAdapterFromName(Attributes attrs, Name name, String nameInNamespace) { String nameString; String referralUrl = ""; if (name instanceof CompositeName) { // Which it most certainly will be, and therein lies the // problem. CompositeName.toString() completely screws up the // formatting // in some cases, particularly when backslashes are involved. nameString = LdapUtils.convertCompositeNameToString((CompositeName) name); } else { LOG.warn( "Expecting a CompositeName as input to getObjectInstance but received a '" + name.getClass().toString() + "' - using toString and proceeding with undefined results"); nameString = name.toString(); } if (nameString.startsWith(LDAP_PROTOCOL_PREFIX) || nameString.startsWith(LDAPS_PROTOCOL_PREFIX)) { if (LOG.isDebugEnabled()) { LOG.debug( "Received name '" + nameString + "' contains protocol delimiter; indicating a referral." + "Stripping protocol and address info to enable construction of a proper LdapName"); } try { URI url = new URI(nameString); String pathString = url.getPath(); referralUrl = nameString.substring(0, nameString.length() - pathString.length()); if (StringUtils.hasLength(pathString) && pathString.startsWith("/")) { // We don't want any slash in the beginning of the // Distinguished Name. pathString = pathString.substring(1); } nameString = pathString; } catch (URISyntaxException e) { throw new IllegalArgumentException( "Supplied name starts with protocol prefix indicating a referral," + " but is not possible to parse to an URI", e); } if (LOG.isDebugEnabled()) { LOG.debug("Resulting name after removal of referral information: '" + nameString + "'"); } } DirContextAdapter dirContextAdapter = new DirContextAdapter( attrs, LdapUtils.newLdapName(nameString), LdapUtils.newLdapName(nameInNamespace), referralUrl); dirContextAdapter.setUpdateMode(true); return dirContextAdapter; }
@Override public Person doMapFromContext(DirContextOperations context) { Person person = new Person(); LdapName dn = LdapUtils.newLdapName(context.getDn()); person.setCountry(LdapUtils.getStringValue(dn, 0)); person.setCompany(LdapUtils.getStringValue(dn, 1)); person.setFullName(context.getStringAttribute("cn")); person.setLastName(context.getStringAttribute("sn")); person.setDescription(context.getStringAttribute("description")); person.setPhone(context.getStringAttribute("telephoneNumber")); return person; }
@Before public void prepareTestedInstance() throws Exception { LdapTestUtils.cleanAndSetup( contextSource, LdapUtils.newLdapName("ou=People"), new ClassPathResource("/setup_data.ldif")); }
@Test public void testRecordOperation() { final LdapName expectedTempName = LdapUtils.newLdapName("cn=john doe_temp"); final LdapName expectedDn = LdapUtils.newLdapName("cn=john doe"); UnbindOperationRecorder tested = new UnbindOperationRecorder(ldapOperationsMock, renamingStrategyMock); when(renamingStrategyMock.getTemporaryName(expectedDn)).thenReturn(expectedTempName); // Perform test CompensatingTransactionOperationExecutor operation = tested.recordOperation(new Object[] {expectedDn}); // Verify result assertThat(operation instanceof UnbindOperationExecutor).isTrue(); UnbindOperationExecutor rollbackOperation = (UnbindOperationExecutor) operation; assertThat(rollbackOperation.getLdapOperations()).isSameAs(ldapOperationsMock); assertThat(rollbackOperation.getOriginalDn()).isSameAs(expectedDn); assertThat(rollbackOperation.getTemporaryDn()).isSameAs(expectedTempName); }
/** * This method depends on a DirObjectFactory ({@link * org.springframework.ldap.core.support.DefaultDirObjectFactory}) being set in the ContextSource. */ @Test public void testLookup_Plain() { String expectedDn = "cn=Some Person2, ou=company1, ou=Sweden," + base; DirContextAdapter result = (DirContextAdapter) tested.lookup(expectedDn); assertEquals("Some Person2", result.getStringAttribute("cn")); assertEquals("Person2", result.getStringAttribute("sn")); assertEquals("Sweden, Company1, Some Person2", result.getStringAttribute("description")); LdapName expectedName = LdapUtils.newLdapName(expectedDn); assertEquals(expectedName, result.getDn()); assertEquals(expectedDn, result.getNameInNamespace()); }
private static void loadLdif(DirContext context, Resource ldifFile) throws IOException { try { LdapName baseDn = (LdapName) context.getEnvironment().get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY); LdifParser parser = new LdifParser(ldifFile); parser.open(); while (parser.hasMoreRecords()) { LdapAttributes record = parser.getRecord(); LdapName dn = record.getName(); if (baseDn != null) { dn = LdapUtils.removeFirst(dn, baseDn); } context.bind(dn, null, record); } } catch (NamingException e) { throw new RuntimeException("Failed to populate LDIF", e); } }
@Test public void testBindAndUnbind_Plain() { DirContextAdapter adapter = new DirContextAdapter(); adapter.setAttributeValues("objectclass", new String[] {"top", "person"}); adapter.setAttributeValue("cn", "Some Person4"); adapter.setAttributeValue("sn", "Person4"); tested.bind("cn=Some Person4, ou=company1, ou=Sweden," + base, adapter, null); DirContextAdapter result = (DirContextAdapter) tested.lookup("cn=Some Person4, ou=company1, ou=Sweden," + base); assertThat(result.getStringAttribute("cn")).isEqualTo("Some Person4"); assertThat(result.getStringAttribute("sn")).isEqualTo("Person4"); assertThat(result.getDn()) .isEqualTo(LdapUtils.newLdapName("cn=Some Person4,ou=company1,ou=Sweden," + base)); tested.unbind("cn=Some Person4,ou=company1,ou=Sweden," + base); try { tested.lookup("cn=Some Person4, ou=company1, ou=Sweden," + base); fail("NameNotFoundException expected"); } catch (NameNotFoundException expected) { assertThat(true).isTrue(); } }
@Override protected Name getRoot() { return LdapUtils.newLdapName(base); }
@After public void cleanup() throws Exception { LdapTestUtils.clearSubContexts(contextSource, LdapUtils.newLdapName("ou=People")); }
/** * Lookup all values for the specified attribute, looping through the results incrementally if * necessary. * * @param ldapOperations The instance to use for performing the actual lookup. * @param dn The distinguished name of the object to find. * @param attribute name of the attribute to request. * @return a list with all attribute values found for the requested attribute. Never <code>null * </code>, an empty list indicates that the attribute was not set or empty. */ public static List<Object> lookupAttributeValues( LdapOperations ldapOperations, String dn, String attribute) { return lookupAttributeValues(ldapOperations, LdapUtils.newLdapName(dn), attribute); }
/** * Lookup all values for the specified attributes, looping through the results incrementally if * necessary. * * @param ldapOperations The instance to use for performing the actual lookup. * @param dn The distinguished name of the object to find. * @param attributes names of the attributes to request. * @return an Attributes instance, populated with all found values for the requested attributes. * Never <code>null</code>, though the actual attributes may not be set if they was not set on * the requested object. */ public static Attributes lookupAttributes( LdapOperations ldapOperations, String dn, String[] attributes) { return lookupAttributes(ldapOperations, LdapUtils.newLdapName(dn), attributes); }
public class TestSearchForPeople { // Base DN for test data private static final LdapName baseName = LdapUtils.newLdapName("o=Whoniverse"); private static final String PRINCIPAL = "uid=admin,ou=system"; private static final String CREDENTIALS = "secret"; // This port MUST be free on local host for these unit tests to function. private static int PORT = 10389; @BeforeClass public static void setUpClass() throws Exception { // Start an LDAP server and import test data LdapTestUtils.startEmbeddedServer(PORT, baseName.toString(), "odm-test"); } @AfterClass public static void tearDownClass() throws Exception { LdapTestUtils.shutdownEmbeddedServer(); } @Before public void setUp() throws Exception { // Bind to the directory LdapContextSource contextSource = new LdapContextSource(); contextSource.setUrl("ldap://127.0.0.1:" + PORT); contextSource.setUserDn(""); contextSource.setPassword(""); contextSource.setPooled(false); contextSource.afterPropertiesSet(); // Create the Sprint LDAP template LdapTemplate template = new LdapTemplate(contextSource); // Clear out any old data - and load the test data LdapTestUtils.cleanAndSetup( template.getContextSource(), baseName, new ClassPathResource("testdata.ldif")); } @After public void tearDown() {} // Very simple test - mainly just to exercise the code and to // ensure we get representative test coverage @Test public void runSample() throws Exception { PrintStream originalOut = System.out; try { ByteArrayOutputStream output = new ByteArrayOutputStream(); System.setOut(new PrintStream(output)); SearchForPeople.main(null); assertEquals( "dn=cn=Bramble Harvey,ou=Doctors,o=Whoniverse | objectClass=[person, top] | cn=[Bramble Harvey] | sn=[Harvey] | description=[Really not a Doctor] | userPassword=[] | telephoneNumber=[22] | seeAlso=[]", output.toString().trim()); } finally { System.setOut(originalOut); } } }