private SearchResultHandler execute(Collection<String> baseDns, Query query) { List<NamingEnumeration<SearchResult>> searchResults = new ArrayList<>(); LOG.debug("Executing a query: '{}' with base DNs {}.", query.getFilter(), baseDns); for (String aBaseDn : baseDns) { try { NamingEnumeration<SearchResult> searchResult = ctx.search(aBaseDn, query.getFilter(), query.getControls()); if (searchResult != null) { searchResults.add(searchResult); } } catch (NamingException ex) { LOG.debug("Exception happened for query '" + query.getFilter() + "' with base DN '" + aBaseDn + "'", ex); } } return new SearchResultHandler(searchResults); } }
/** * Checks whether search result contains exactly one entry. * @return true if the search result contains a single entry. * @throws NamingException */ public boolean hasSingleResult() throws NamingException { List<String> allResults = getAllLdapNames(); return allResults != null && allResults.size() == 1; }
/** * {@inheritDoc} */ @Override public List<String> executeCustomQuery(String query) throws NamingException { return execute(Collections.singletonList(baseDn), queries.customQuery(query)) .getAllLdapNamesAndAttributes(); }
@Test public void testGetAllLdapNamesNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); List<String> actual = handler.getAllLdapNames(); assertEquals("Resultset size", 0, actual.size()); assertAllNamingEnumerationsClosed(resultCollection); }
@Test public void testHasSingleResult() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1"); handler = new SearchResultHandler(resultCollection); assertTrue(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); }
@Test(expected = NamingException.class) public void testGetSingleLdapNameNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); try { handler.getSingleLdapName(); } finally { assertAllNamingEnumerationsClosed(resultCollection); } }
@Test public void testHandle() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2", "3"); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList("1", "2"); final List<String> actual = new ArrayList<>(); handler.handle(new SearchResultHandler.RecordProcessor() { @Override public boolean process(SearchResult record) throws NamingException { actual.add(record.getNameInNamespace()); return actual.size() < 2; } }); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); }
@Test public void testGetAllLdapNamesAndAttributes() throws NamingException { SearchResult searchResult1 = mockSearchResult("cn=a1,dc=b,dc=c", mockAttributes("attr1", "attr1value1")); SearchResult searchResult2 = mockSearchResult("cn=a2,dc=b,dc=c", mockAttributes("attr1", "attr1value2", "attr2", "attr2value1")); SearchResult searchResult3 = mockSearchResult("cn=a3,dc=b,dc=c", mockAttributes("attr1", "attr1value3", "attr1", "attr1value4")); SearchResult searchResult4 = mockSearchResult("cn=a4,dc=b,dc=c", mockEmptyAttributes()); MockResultCollection resultCollection = MockResultCollection.create() .addSearchResults(searchResult1) .addSearchResults(searchResult2, searchResult3) .addSearchResults(searchResult4); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList( "cn=a1,dc=b,dc=c", "attr1value1", "cn=a2,dc=b,dc=c", "attr1value2", "attr2value1", "cn=a3,dc=b,dc=c", "attr1value3", "attr1value4", "cn=a4,dc=b,dc=c"); Collections.sort(expected); List<String> actual = handler.getAllLdapNamesAndAttributes(); Collections.sort(actual); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); }
/** * Returns all entries from the search result. * @return a list of names in the namespace * @throws NamingException */ public List<String> getAllLdapNames() throws NamingException { final List<String> result = new ArrayList<>(); handle(new RecordProcessor() { @Override public boolean process(SearchResult record) throws NamingException { result.add(record.getNameInNamespace()); return true; } }); return result; }
/** * {@inheritDoc} */ @Override public boolean isUserMemberOfGroup(String user, String groupDn) throws NamingException { String userId = LdapUtils.extractUserName(user); return execute(userBases, queries.isUserMemberOfGroup(userId, groupDn)).hasSingleResult(); }
/** * {@inheritDoc} */ @Override public String findGroupDn(String group) throws NamingException { return execute(groupBases, queries.findGroupDnById(group)).getSingleLdapName(); }
@Test public void testGetAllLdapNamesWithExceptionInNamingEnumerationClose() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2"); doThrow(NamingException.class).when(resultCollection.iterator().next()).close(); handler = new SearchResultHandler(resultCollection); List<String> actual = handler.getAllLdapNames(); assertEquals("Resultset size", 2, actual.size()); assertAllNamingEnumerationsClosed(resultCollection); }
@Test public void testHasSingleResultNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); assertFalse(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); }
@Test public void testGetSingleLdapName() throws NamingException { String objectDn = "cn=a,dc=b,dc=c"; MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult() .addSearchResultWithDns(objectDn); handler = new SearchResultHandler(resultCollection); String expected = objectDn; String actual = handler.getSingleLdapName(); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); }
/** * Returns all entries and all attributes for these entries. * @return a list that includes all entries and all attributes from these entries. * @throws NamingException */ public List<String> getAllLdapNamesAndAttributes() throws NamingException { final List<String> result = new ArrayList<>(); handle(new RecordProcessor() { @Override public boolean process(SearchResult record) throws NamingException { result.add(record.getNameInNamespace()); NamingEnumeration<? extends Attribute> allAttributes = record.getAttributes().getAll(); while(allAttributes.hasMore()) { Attribute attribute = allAttributes.next(); addAllAttributeValuesToResult(attribute.getAll()); } return true; } private void addAllAttributeValuesToResult(NamingEnumeration values) throws NamingException { while(values.hasMore()) { result.add(String.valueOf(values.next())); } } }); return result; }
/** * {@inheritDoc} */ @Override public boolean isUserMemberOfGroup(String user, String groupDn) throws NamingException { String userId = LdapUtils.extractUserName(user); return execute(userBases, queries.isUserMemberOfGroup(userId, groupDn)).hasSingleResult(); }
/** * {@inheritDoc} */ @Override public String findGroupDn(String group) throws NamingException { return execute(groupBases, queries.findGroupDnById(group)).getSingleLdapName(); }
@Test public void testGetAllLdapNames() throws NamingException { String objectDn1 = "cn=a1,dc=b,dc=c"; String objectDn2 = "cn=a2,dc=b,dc=c"; String objectDn3 = "cn=a3,dc=b,dc=c"; MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns(objectDn1) .addSearchResultWithDns(objectDn2, objectDn3); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList(objectDn1, objectDn2, objectDn3); Collections.sort(expected); List<String> actual = handler.getAllLdapNames(); Collections.sort(actual); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); }
@Test public void testHasSingleResultManyRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2"); handler = new SearchResultHandler(resultCollection); assertFalse(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); }
/** * Returns a single entry from the search result. * Throws {@code NamingException} if the search result doesn't contain exactly one entry. * @return name in the namespace * @throws NamingException */ public String getSingleLdapName() throws NamingException { List<String> allLdapNames = getAllLdapNames(); if (allLdapNames.size() == 1) { return allLdapNames.get(0); } throw new NamingException("Single result was expected"); }