You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2020/11/26 17:22:32 UTC

svn commit: r1883842 - in /jackrabbit/oak/trunk/oak-auth-ldap: ./ src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/ src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/ src/test/java/org/apache/jackrabbit/oak/s...

Author: angela
Date: Thu Nov 26 17:22:32 2020
New Revision: 1883842

URL: http://svn.apache.org/viewvc?rev=1883842&view=rev
Log:
OAK-9288 : Simplify LdapIdentityProvider
OAK-9275 : restore test coverage of oak-auth-ldap

Added:
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProviderTest.java
      - copied, changed from r1883841, jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapProviderTest.java
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java   (with props)
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java   (with props)
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/impl/
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/impl/apache-ds-tutorial.ldif
      - copied unchanged from r1883841, jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/apache-ds-tutorial.ldif
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/impl/erroneous.ldif
      - copied unchanged from r1883841, jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/erroneous.ldif
Removed:
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapProviderTest.java
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/apache-ds-tutorial.ldif
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/resources/org/apache/jackrabbit/oak/security/authentication/ldap/erroneous.ldif
Modified:
    jackrabbit/oak/trunk/oak-auth-ldap/pom.xml
    jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/AbstractLdapIdentityProviderTest.java
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapGroupTest.java

Modified: jackrabbit/oak/trunk/oak-auth-ldap/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/pom.xml?rev=1883842&r1=1883841&r2=1883842&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/pom.xml Thu Nov 26 17:22:32 2020
@@ -35,8 +35,8 @@
         <apacheds.test.version>2.0.0-M24</apacheds.test.version>
         <!-- enable execution of jacoco and set minimal line coverage -->
         <skip.coverage>false</skip.coverage>
-        <minimum.line.coverage>0.89</minimum.line.coverage>
-        <minimum.branch.coverage>0.82</minimum.branch.coverage>
+        <minimum.line.coverage>0.92</minimum.line.coverage>
+        <minimum.branch.coverage>0.86</minimum.branch.coverage>
     </properties>
 
     <build>

Modified: jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java?rev=1883842&r1=1883841&r2=1883842&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java Thu Nov 26 17:22:32 2020
@@ -258,9 +258,8 @@ public class LdapIdentityProvider implem
         try {
             Entry entry = getEntry(connection, config.getUserConfig(), userId, config.getCustomAttributes());
             timer.mark("lookup");
-            if (log.isDebugEnabled()) {
-                log.debug("getUser({}) {}", userId, timer.getString());
-            }
+            debug("getUser({}) {}", userId, timer.getString());
+
             if (entry != null) {
                 return createUser(entry, userId);
             } else {
@@ -281,9 +280,8 @@ public class LdapIdentityProvider implem
         try {
             Entry entry = getEntry(connection, config.getGroupConfig(), name, config.getCustomAttributes());
             timer.mark("lookup");
-            if (log.isDebugEnabled()) {
-                log.debug("getGroup({}) {}", name, timer.getString());
-            }
+            debug("getGroup({}) {}", name, timer.getString());
+
             if (entry != null) {
                 return createGroup(entry, name);
             } else {
@@ -363,39 +361,45 @@ public class LdapIdentityProvider implem
             LdapConnection connection = null;
             try {
                 DebugTimer timer = new DebugTimer();
-                if (userPool == null) {
-                    connection = userConnectionFactory.create();
-                } else {
-                    connection = userPool.getConnection();
-                }
+                connection = createUserConnection();
                 timer.mark("connect");
                 connection.bind(user.getEntry().getDn(), new String(creds.getPassword()));
-                //connection.bind(user.getExternalId().getId(), new String(creds.getPassword()));
                 timer.mark("bind");
-                if (log.isDebugEnabled()) {
-                    log.debug("authenticate({}) {}", user.getId(), timer.getString());
-                }
+                debug("authenticate({}) {}", user.getId(), timer.getString());
             } catch (LdapAuthenticationException e) {
                 throw new LoginException("Unable to authenticate against LDAP server: " + e.getMessage());
             } catch (Exception e) {
-                throw new ExternalIdentityException("Error while binding user credentials", e);
+                throw error(e, "Error while binding user credentials");
             } finally {
-                if (connection != null) {
-                    try {
-                        if (userPool == null) {
-                            userConnectionFactory.destroyObject(connection);
-                        } else {
-                            userPool.releaseConnection(connection);
-                        }
-                    } catch (Exception e) {
-                        // ignore
-                    }
-                }
+                disconnectUserConnection(connection);
             }
         }
         return user;
     }
 
+    @NotNull
+    private LdapConnection createUserConnection() throws Exception {
+        if (userPool == null) {
+            return userConnectionFactory.create();
+        } else {
+            return userPool.getConnection();
+        }
+    }
+
+    private void disconnectUserConnection(@Nullable LdapConnection connection) {
+        if (connection != null) {
+            try {
+                if (userPool == null) {
+                    userConnectionFactory.destroyObject(connection);
+                } else {
+                    userPool.releaseConnection(connection);
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
     //-----------------------------------------------------------< internal >---
 
     /**
@@ -421,11 +425,9 @@ public class LdapIdentityProvider implem
             req.setBase(new Dn(config.getGroupConfig().getBaseDN()));
             req.setFilter(searchFilter);
 
-            if (log.isDebugEnabled()) {
-                log.debug("getDeclaredGroupRefs: using SearchRequest {}.", req);
-            }
+            debug("getDeclaredGroupRefs: using SearchRequest {}.", req);
 
-            Map<String, ExternalIdentityRef> groups = new HashMap<String, ExternalIdentityRef>();
+            Map<String, ExternalIdentityRef> groups = new HashMap<>();
             DebugTimer timer = new DebugTimer();
             connection = connect();
             timer.mark("connect");
@@ -441,22 +443,14 @@ public class LdapIdentityProvider implem
                 }
             }
             timer.mark("iterate");
-            if (log.isDebugEnabled()) {
-                log.debug("getDeclaredGroupRefs: search below {} with {} found {} entries. {}",
+            debug("getDeclaredGroupRefs: search below {} with {} found {} entries. {}",
                         config.getGroupConfig().getBaseDN(), searchFilter, groups.size(), timer.getString());
-            }
+
             return groups;
         } catch (Exception e) {
-            log.error("Error during ldap membership search." ,e);
-            throw new ExternalIdentityException("Error during ldap membership search.", e);
+            throw error(e, "Error during ldap membership search.");
         } finally {
-            if (searchCursor != null) {
-                try {
-                    searchCursor.close();
-                } catch (IOException e) {
-                    log.warn("Failed to close search cursor.", e);
-                }
-            }
+            closeSearchCursor(searchCursor);
             disconnect(connection);
         }
     }
@@ -473,7 +467,7 @@ public class LdapIdentityProvider implem
         }
         LdapConnection connection = null;
         try {
-            Map<String, ExternalIdentityRef> members = new HashMap<String, ExternalIdentityRef>();
+            Map<String, ExternalIdentityRef> members = new HashMap<>();
             DebugTimer timer = new DebugTimer();
             connection = connect();
             timer.mark("connect");
@@ -489,14 +483,11 @@ public class LdapIdentityProvider implem
                 }
             }
             timer.mark("iterate");
-            if (log.isDebugEnabled()) {
-                log.debug("members lookup of {} found {} members. {}", ref.getId(), members.size(), timer.getString());
-            }
+            debug("members lookup of {} found {} members. {}", ref.getId(), members.size(), timer.getString());
+
             return members;
         } catch (Exception e) {
-            String msg = "Error during ldap group members lookup.";
-            log.error(msg ,e);
-            throw new ExternalIdentityException(msg, e);
+            throw error(e, "Error during ldap group members lookup.");
         } finally {
             disconnect(connection);
         }
@@ -606,9 +597,7 @@ public class LdapIdentityProvider implem
         req.setBase(new Dn(idConfig.getBaseDN()));
         req.setFilter(searchFilter);
 
-        if (log.isDebugEnabled()) {
-            log.debug("getEntry: using SearchRequest {}.", req);
-        }
+        debug("getEntry: using SearchRequest {}.", req);
 
         // Process the request
         SearchCursor searchCursor = null;
@@ -627,20 +616,12 @@ public class LdapIdentityProvider implem
                 }
             }
         } finally {
-            if (searchCursor != null) {
-                try {
-                    searchCursor.close();
-                } catch (IOException e) {
-                    log.warn("Failed to close search cursor.", e);
-                }
-            }
+            closeSearchCursor(searchCursor);
         }
-        if (log.isDebugEnabled()) {
-            if (resultEntry == null) {
-                log.debug("getEntry: search below {} with {} found 0 entries.", idConfig.getBaseDN(), searchFilter);
-            } else {
-                log.debug("getEntry: search below {} with {} found {}", idConfig.getBaseDN(), searchFilter, resultEntry.getDn());
-            }
+        if (resultEntry == null) {
+            debug("getEntry: search below {} with {} found 0 entries.", idConfig.getBaseDN(), searchFilter);
+        } else {
+            debug("getEntry: search below {} with {} found {}", idConfig.getBaseDN(), searchFilter, resultEntry.getDn());
         }
         return resultEntry;
     }
@@ -674,7 +655,7 @@ public class LdapIdentityProvider implem
         private final LdapProviderConfig.Identity idConfig;
 
         private byte[] cookie;
-        private List page = Collections.emptyList();
+        private List<Entry> page = Collections.emptyList();
         private boolean searchComplete;
         private int pos = -1;
 
@@ -697,7 +678,7 @@ public class LdapIdentityProvider implem
         public Entry next() {
             if (hasNext()) {
                 try {
-                    Entry entry = (Entry) page.get(pos);
+                    Entry entry = page.get(pos);
                     findNextEntry();
                     return entry;
                 } catch (LdapException | CursorException | ExternalIdentityException e) {
@@ -714,7 +695,7 @@ public class LdapIdentityProvider implem
 
         //-------------------------------------------------------< internal >---
 
-        private SearchRequest createSearchRequest(LdapConnection connection, byte[] cookie, @NotNull String[] userAttributes) throws LdapException {
+        private SearchRequest createSearchRequest(byte[] cookie, @NotNull String[] userAttributes) throws LdapException {
             SearchRequest req = new SearchRequestImpl();
             req.setScope(SearchScope.SUBTREE);
             if (userAttributes.length == 0) {
@@ -743,12 +724,11 @@ public class LdapIdentityProvider implem
             DebugTimer timer = new DebugTimer();
             LdapConnection connection = connect();
             timer.mark("connect");
-            page = new ArrayList<Entry>();
+            page = new ArrayList<>();
             try {
-                SearchRequest req = createSearchRequest(connection, cookie, config.getCustomAttributes());
-                if (log.isDebugEnabled()) {
-                    log.debug("loadNextPage: using SearchRequest {}.", req);
-                }
+                SearchRequest req = createSearchRequest(cookie, config.getCustomAttributes());
+                debug("loadNextPage: using SearchRequest {}.", req);
+
                 searchCursor = connection.search(req);
                 while (searchCursor.next()) {
                     Response response = searchCursor.get();
@@ -756,9 +736,7 @@ public class LdapIdentityProvider implem
                     if (response instanceof SearchResultEntry) {
                         Entry resultEntry = ((SearchResultEntry) response).getEntry();
                         page.add(resultEntry);
-                        if (log.isDebugEnabled()) {
-                            log.debug("loadNextPage: search below {} with {} found {}", idConfig.getBaseDN(), searchFilter, resultEntry.getDn());
-                        }
+                        debug("loadNextPage: search below {} with {} found {}", idConfig.getBaseDN(), searchFilter, resultEntry.getDn());
                     }
                 }
 
@@ -778,13 +756,7 @@ public class LdapIdentityProvider implem
 
                 return !page.isEmpty();
             } finally {
-                if (searchCursor != null) {
-                    try {
-                        searchCursor.close();
-                    } catch (IOException e) {
-                        log.warn("Failed to close search cursor.", e);
-                    }
-                }
+                closeSearchCursor(searchCursor);
                 disconnect(connection);
             }
         }
@@ -848,7 +820,7 @@ public class LdapIdentityProvider implem
                 final Object propValue;
                 // for multivalue properties, store as collection
                 if (attr.size() > 1) {
-                    List<String> values = new ArrayList();
+                    List<String> values = new ArrayList<>();
                     for (Value value : attr) {
                         values.add(value.getString());
                     }
@@ -870,9 +842,7 @@ public class LdapIdentityProvider implem
                 return adminPool.getConnection();
             }
         } catch (Exception e) {
-            String msg = "Error while connecting to the ldap server.";
-            log.error(msg, e);
-            throw new ExternalIdentityException(msg, e);
+            throw error(e, "Error while connecting to the ldap server.");
         }
     }
 
@@ -912,8 +882,29 @@ public class LdapIdentityProvider implem
     }
 
     private static ExternalIdentityException lookupFailedException(@NotNull Exception e, @Nullable DebugTimer timer) {
-        String msg = "Error during ldap lookup. ";
-        log.error(msg + ((timer != null) ? timer.getString() : ""), e);
+        String msg = "Error during ldap lookup. {}";
+        log.error(msg, ((timer != null) ? timer.getString() : ""), e);
         return new ExternalIdentityException(msg, e);
     }
+
+    private static ExternalIdentityException error(@NotNull Exception e, @NotNull String msg) {
+        log.error(msg, e);
+        return new ExternalIdentityException(msg, e);
+    }
+
+    private static void debug(@NotNull String msg, @NotNull Object... vars) {
+        if (log.isDebugEnabled()) {
+            log.debug(msg, vars);
+        }
+    }
+
+    private static void closeSearchCursor(@Nullable SearchCursor searchCursor) {
+        if (searchCursor != null) {
+            try {
+                searchCursor.close();
+            } catch (IOException e) {
+                log.warn("Failed to close search cursor.", e);
+            }
+        }
+    }
 }

Modified: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/AbstractLdapIdentityProviderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/AbstractLdapIdentityProviderTest.java?rev=1883842&r1=1883841&r2=1883842&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/AbstractLdapIdentityProviderTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/AbstractLdapIdentityProviderTest.java Thu Nov 26 17:22:32 2020
@@ -70,7 +70,6 @@ public abstract class AbstractLdapIdenti
     protected LdapServerClassLoader.Proxy proxy;
 
     private static final String TUTORIAL_LDIF = "apache-ds-tutorial.ldif";
-    public static final String ERRONEOUS_LDIF = "erroneous.ldif";
     public static final String IDP_NAME = "ldap";
 
     public static final String[] DEFAULT_USER_PROPERTIES = new String[] { "objectclass", "uid", "givenname", "description", "sn", "cn"};
@@ -146,7 +145,7 @@ public abstract class AbstractLdapIdenti
     }
 
     public static void assertIfEquals(String message, String[] expected, Iterable<ExternalIdentityRef> result) {
-        List<String> dns = new LinkedList<String>();
+        List<String> dns = new LinkedList<>();
         for (ExternalIdentityRef ref: result) {
             dns.add(ref.getId());
         }

Modified: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapGroupTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapGroupTest.java?rev=1883842&r1=1883841&r2=1883842&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapGroupTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapGroupTest.java Thu Nov 26 17:22:32 2020
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertEqu
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
 
 public class LdapGroupTest extends LdapIdentityTest {
 

Copied: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProviderTest.java (from r1883841, jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapProviderTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProviderTest.java?p2=jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProviderTest.java&p1=jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapProviderTest.java&r1=1883841&r2=1883842&rev=1883842&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LdapProviderTest.java (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProviderTest.java Thu Nov 26 17:22:32 2020
@@ -15,15 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.jackrabbit.oak.security.authentication.ldap;
+package org.apache.jackrabbit.oak.security.authentication.ldap.impl;
 
+import com.google.common.base.Function;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Iterators;
 import org.apache.directory.api.util.Strings;
-import org.apache.jackrabbit.oak.security.authentication.ldap.impl.AbstractLdapIdentityProviderTest;
-import org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentity;
-import org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapIdentityProvider;
-import org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapUser;
 import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalGroup;
 import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
 import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityException;
@@ -39,6 +37,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapProviderConfig.PARAM_USER_EXTRA_FILTER_DEFAULT;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -47,7 +46,9 @@ import static org.junit.Assert.assertTha
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-public class LdapProviderTest extends AbstractLdapIdentityProviderTest {
+public class LdapIdentityProviderTest extends AbstractLdapIdentityProviderTest {
+
+    private static final String ERRONEOUS_LDIF = "erroneous.ldif";
 
     @Test
     public void testGetUserByRef() throws Exception {
@@ -55,15 +56,27 @@ public class LdapProviderTest extends Ab
         ExternalIdentity id = idp.getIdentity(ref);
         assertTrue("User instance", id instanceof ExternalUser);
         assertEquals("User ID", TEST_USER1_UID, id.getId());
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_USER1_UID, IDP_NAME);
-        id = idp.getIdentity(ref);
-        assertTrue("User instance", id instanceof ExternalUser);
-        assertEquals("User ID", TEST_USER1_UID, id.getId());
     }
-    
+
+    @Test
+    public void testListUsers() throws Exception {
+        Iterator<ExternalUser> users = idp.listUsers();
+        Iterator<String> ids = Iterators.transform(users, externalUser -> externalUser.getId());
+
+        Set<String> expectedIds = ImmutableSet.of(TEST_USER0_UID, TEST_USER1_UID, TEST_USER5_UID, "hnelson", "thardy", "tquist", "fchristi", "wbush", "cbuckley", "jhallett", "mchrysta", "wbligh", "jfryer");
+        assertEquals(expectedIds, ImmutableSet.copyOf(ids));
+    }
+
+    @Test
+    public void testListUsersWithExtraFilter() throws Exception {
+        providerConfig.getUserConfig().setExtraFilter(PARAM_USER_EXTRA_FILTER_DEFAULT);
+        Iterator<ExternalUser> users = idp.listUsers();
+        Iterator<String> ids = Iterators.transform(users, externalUser -> externalUser.getId());
+
+        Set<String> expectedIds = ImmutableSet.of(TEST_USER0_UID, TEST_USER1_UID, TEST_USER5_UID, "hnelson", "thardy", "tquist", "fchristi", "wbush", "cbuckley", "jhallett", "mchrysta", "wbligh", "jfryer");
+        assertEquals(expectedIds, ImmutableSet.copyOf(ids));
+    }
+
     /**
      * Test case to reproduce OAK-3396 where an ldap user entry
      * without a uid caused a NullpointerException in LdapIdentityProvider.createUser
@@ -112,83 +125,6 @@ public class LdapProviderTest extends Ab
     @Test
     public void testAuthenticate() throws Exception {
         authenticateInternal(idp, TEST_USER1_DN);
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateInternal(idp, TEST_USER1_UID);
-    }
-
-    @Test
-    public void testAuthenticateValidateFalseFalse() throws Exception {
-        providerConfig.getAdminPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(false);
-        providerConfig.getUserPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(false);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_DN);
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_UID);
-    }
-
-    @Test
-    public void testAuthenticateValidateFalseTrue() throws Exception {
-        providerConfig.getAdminPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(false);
-        providerConfig.getUserPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_DN);
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_UID);
-    }
-
-    @Test
-    public void testAuthenticateValidateTrueFalse() throws Exception {
-        providerConfig.getAdminPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(true);
-        providerConfig.getUserPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(false);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_DN);
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_UID);
-    }
-
-    @Test
-    public void testAuthenticateValidateTrueTrue() throws Exception {
-        providerConfig.getAdminPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(true);
-        providerConfig.getUserPoolConfig()
-                .setMaxActive(2)
-                .setLookupOnValidate(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_DN);
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        authenticateValidateInternal(idp, TEST_USER1_UID);
     }
 
     @Test
@@ -198,14 +134,6 @@ public class LdapProviderTest extends Ab
         assertNotNull("User 1 must authenticate", user);
         assertEquals("User Ref", TEST_USER1_DN, ((LdapUser)user).getEntry().getDn().getName());
         assertEquals("User Ref", TEST_USER1_DN, user.getExternalId().getId());
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        user = idp.authenticate(creds);
-        assertNotNull("User 1 must authenticate", user);
-        assertEquals("User Ref", TEST_USER1_DN, ((LdapUser)user).getEntry().getDn().getName());
-        assertEquals("User Ref", TEST_USER1_UID.toUpperCase(), user.getExternalId().getId());
     }
 
     @Test
@@ -231,12 +159,6 @@ public class LdapProviderTest extends Ab
         ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER1_DN, "foobar");
         ExternalIdentity id = idp.getIdentity(ref);
         assertNull("Foreign ref must be null", id);
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_USER1_UID, "foobar");
-        id = idp.getIdentity(ref);
-        assertNull("Foreign ref must be null", id);
     }
 
     @Test
@@ -244,11 +166,6 @@ public class LdapProviderTest extends Ab
         ExternalIdentityRef ref = new ExternalIdentityRef("bla=foo," + TEST_USER1_DN, IDP_NAME);
         ExternalIdentity id = idp.getIdentity(ref);
         assertNull("Unknown user must return null", id);
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        id = idp.getIdentity(ref);
-        assertNull("Unknown user must return null", id);
     }
 
     @Test
@@ -257,12 +174,6 @@ public class LdapProviderTest extends Ab
         ExternalIdentity id = idp.getIdentity(ref);
         assertTrue("Group instance", id instanceof ExternalGroup);
         assertEquals("Group Name", TEST_GROUP1_NAME, id.getId());
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_GROUP1_NAME, IDP_NAME);
-        id = idp.getIdentity(ref);
-        assertEquals("Group Name", TEST_GROUP1_NAME, id.getId());
     }
 
     @Test
@@ -279,53 +190,58 @@ public class LdapProviderTest extends Ab
     }
 
     @Test
-    public void testGetMembers() throws Exception {
+    public void testGetDeclaredMembersByRef() throws Exception {
         ExternalIdentityRef ref = new ExternalIdentityRef(TEST_GROUP1_DN, IDP_NAME);
         ExternalIdentity id = idp.getIdentity(ref);
         assertTrue("Group instance", id instanceof ExternalGroup);
         ExternalGroup grp = (ExternalGroup) id;
         assertIfEquals("Group members", TEST_GROUP1_MEMBERS, grp.getDeclaredMembers());
+    }
 
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_GROUP1_NAME, IDP_NAME);
-        id = idp.getIdentity(ref);
-        assertTrue("Group instance", id instanceof ExternalGroup);
-        grp = (ExternalGroup) id;
-        assertIfEquals("Group members", TEST_GROUP1_MEMBERS, grp.getDeclaredMembers());
+
+    @Test
+    public void testGetDeclaredMembers() throws Exception {
+        ExternalGroup gr = idp.getGroup(TEST_GROUP1_NAME);
+        Iterable<ExternalIdentityRef> memberrefs = gr.getDeclaredMembers();
+        Iterable<String> memberIds = Iterables.transform(memberrefs, externalIdentityRef -> externalIdentityRef.getId());
+
+        Set<String> expected = ImmutableSet.copyOf(TEST_GROUP1_MEMBERS);
+        assertEquals(expected, ImmutableSet.copyOf(memberIds));
+    }
+
+    @Test
+    public void testGetDeclaredMembersInvalidMemberAttribute() throws Exception {
+        providerConfig.setGroupMemberAttribute("invalid");
+
+        ExternalGroup gr = idp.getGroup(TEST_GROUP1_NAME);
+        Iterable<ExternalIdentityRef> memberrefs = gr.getDeclaredMembers();
+        assertTrue(Iterables.isEmpty(memberrefs));
     }
 
     @Test
-    public void testGetGroups() throws Exception {
+    public void testGetDeclaredGroupsByRef() throws Exception {
         ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER1_DN, IDP_NAME);
         ExternalIdentity id = idp.getIdentity(ref);
         assertTrue("User instance", id instanceof ExternalUser);
         assertIfEquals("Groups", TEST_USER1_GROUPS, id.getDeclaredGroups());
-
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_USER1_UID, IDP_NAME);
-        id = idp.getIdentity(ref);
-        assertTrue("User instance", id instanceof ExternalUser);
-        assertIfEquals("Groups", TEST_USER1_GROUPS, id.getDeclaredGroups());
     }
 
     @Test
-    public void testGetGroups2() throws Exception {
+    public void testGetDeclaredGroupsByRef2() throws Exception {
         ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER0_DN, IDP_NAME);
         ExternalIdentity id = idp.getIdentity(ref);
         assertTrue("User instance", id instanceof ExternalUser);
         assertIfEquals("Groups", TEST_USER0_GROUPS, id.getDeclaredGroups());
+    }
 
-        providerConfig.setUseUidForExtId(true);
-        idp.close();
-        idp = new LdapIdentityProvider(providerConfig);
-        ref = new ExternalIdentityRef(TEST_USER0_UID, IDP_NAME);
-        id = idp.getIdentity(ref);
-        assertTrue("User instance", id instanceof ExternalUser);
-        assertIfEquals("Groups", TEST_USER0_GROUPS, id.getDeclaredGroups());
+    @Test
+    public void testGetDeclaredGroupMissingIdAttribute() throws Exception {
+        providerConfig.getGroupConfig().setIdAttribute(null);
+
+        ExternalUser user = idp.getUser(TEST_USER1_UID);
+        Iterable<ExternalIdentityRef> groupRefs = user.getDeclaredGroups();
+        Iterable<String> groupIds = Iterables.transform(groupRefs, externalIdentityRef -> externalIdentityRef.getId());
+        assertEquals(ImmutableSet.copyOf(TEST_USER1_GROUPS), ImmutableSet.copyOf(groupIds));
     }
 
     @Test
@@ -383,6 +299,17 @@ public class LdapProviderTest extends Ab
         Iterator<ExternalGroup> groups = idp.listGroups();
         Iterator<String> ids = Iterators.transform(groups, externalGroup -> externalGroup.getId());
 
+        Set<String> expectedIds = ImmutableSet.of(TEST_GROUP1_NAME, TEST_GROUP2_NAME, TEST_GROUP3_NAME, "Administrators");
+        assertEquals(expectedIds, ImmutableSet.copyOf(ids));
+    }
+
+    @Test
+    public void testListGroupsWithEmptyExtraFilter() throws Exception {
+        providerConfig.getGroupConfig().setExtraFilter("");
+
+        Iterator<ExternalGroup> groups = idp.listGroups();
+        Iterator<String> ids = Iterators.transform(groups, externalGroup -> externalGroup.getId());
+
         Set<String> expectedIds = ImmutableSet.of(TEST_GROUP1_NAME, TEST_GROUP2_NAME, TEST_GROUP3_NAME, "Administrators");
         assertEquals(expectedIds, ImmutableSet.copyOf(ids));
     }

Added: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java?rev=1883842&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java Thu Nov 26 17:22:32 2020
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.security.authentication.ldap.impl;
+
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.security.user.MembershipWriter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class LookupOnValidateTest extends AbstractLdapIdentityProviderTest {
+
+    @Parameterized.Parameters(name = "name={1}")
+    public static Collection<Object[]> parameters() {
+        return Lists.newArrayList(
+                new Object[] { false, false, false, "False False" },
+                new Object[] { false, true, false, "False True" },
+                new Object[] { true, false, false, "True False"},
+                new Object[] { true, true, false, "True True" },
+                new Object[] { false, false, true, "False False useUidForExtId" },
+                new Object[] { false, true, true, "False True useUidForExtId" },
+                new Object[] { true, false, true, "True False useUidForExtId"},
+                new Object[] { true, true, true, "True True useUidForExtId" });
+    }
+
+    private final boolean adminPoolLookupOnValidate;
+    private final boolean userPoolLookupOnValidate;
+    private final boolean useUidForExtId;
+
+    private final String expectedId;
+
+    public LookupOnValidateTest(boolean adminPoolLookupOnValidate, boolean userPoolLookupOnValidate, boolean useUidForExtId, String name) {
+        this.adminPoolLookupOnValidate = adminPoolLookupOnValidate;
+        this.userPoolLookupOnValidate = userPoolLookupOnValidate;
+        this.useUidForExtId = useUidForExtId;
+
+        if (useUidForExtId) {
+            expectedId = TEST_USER1_UID;
+        } else {
+            expectedId = TEST_USER1_DN;
+        }
+    }
+
+    @Override
+    protected LdapProviderConfig createProviderConfig(String[] userProperties) {
+        LdapProviderConfig config = super.createProviderConfig(userProperties);
+        config.getAdminPoolConfig()
+                .setMaxActive(2)
+                .setLookupOnValidate(adminPoolLookupOnValidate);
+        config.getUserPoolConfig()
+                .setMaxActive(2)
+                .setLookupOnValidate(userPoolLookupOnValidate);
+        config.setUseUidForExtId(useUidForExtId);
+        return config;
+    }
+
+    @Test
+    public void testAuthenticateValidate() throws Exception {
+        authenticateValidateInternal(idp, expectedId);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LookupOnValidateTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java?rev=1883842&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java (added)
+++ jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java Thu Nov 26 17:22:32 2020
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.oak.security.authentication.ldap.impl;
+
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalGroup;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentity;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalIdentityRef;
+import org.apache.jackrabbit.oak.spi.security.authentication.external.ExternalUser;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.jcr.SimpleCredentials;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class UseUidForExtIdTest extends AbstractLdapIdentityProviderTest {
+
+    @Override
+    protected LdapProviderConfig createProviderConfig(String[] userProperties) {
+        LdapProviderConfig config = super.createProviderConfig(userProperties);
+        config.setUseUidForExtId(true);
+        return config;
+    }
+
+    @Test
+    public void testGetUserByRef() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER1_UID, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertTrue("User instance", id instanceof ExternalUser);
+        assertEquals("User ID", TEST_USER1_UID, id.getId());
+    }
+
+    @Test
+    public void testAuthenticate() throws Exception {
+        authenticateInternal(idp, TEST_USER1_UID);
+    }
+
+    @Test
+    public void testAuthenticateCaseInsensitive() throws Exception {
+        SimpleCredentials creds = new SimpleCredentials(TEST_USER1_UID.toUpperCase(), "pass".toCharArray());
+        ExternalUser user = idp.authenticate(creds);
+        assertNotNull("User 1 must authenticate", user);
+        Assert.assertEquals("User Ref", TEST_USER1_DN, ((LdapUser)user).getEntry().getDn().getName());
+        assertEquals("User Ref", TEST_USER1_UID.toUpperCase(), user.getExternalId().getId());
+    }
+
+    @Test
+    public void testGetUserByForeignRef() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER1_UID, "foobar");
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertNull("Foreign ref must be null", id);
+    }
+
+    @Test
+    public void testGetUnknownUserByRef() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef("bla=foo," + TEST_USER1_DN, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertNull("Unknown user must return null", id);
+    }
+
+    @Test
+    public void testGetGroupByRef() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_GROUP1_NAME, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertEquals("Group Name", TEST_GROUP1_NAME, id.getId());
+    }
+
+    @Test
+    public void testGetMembers() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_GROUP1_NAME, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertTrue("Group instance", id instanceof ExternalGroup);
+        ExternalGroup grp = (ExternalGroup) id;
+        assertIfEquals("Group members", TEST_GROUP1_MEMBERS, grp.getDeclaredMembers());
+    }
+
+    @Test
+    public void testGetGroups() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER1_UID, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertTrue("User instance", id instanceof ExternalUser);
+        assertIfEquals("Groups", TEST_USER1_GROUPS, id.getDeclaredGroups());
+    }
+
+    @Test
+    public void testGetGroups2() throws Exception {
+        ExternalIdentityRef ref = new ExternalIdentityRef(TEST_USER0_UID, IDP_NAME);
+        ExternalIdentity id = idp.getIdentity(ref);
+        assertTrue("User instance", id instanceof ExternalUser);
+        assertIfEquals("Groups", TEST_USER0_GROUPS, id.getDeclaredGroups());
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/UseUidForExtIdTest.java
------------------------------------------------------------------------------
    svn:eol-style = native