You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2026/09/30 09:04:04 UTC

(knox) branch master updated: KNOX-3496: LDAP Proxy requests memberOf attribute from backend (#1435)

This is an automated email from the ASF dual-hosted git repository.

smolnar82 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new a42ffc3a1 KNOX-3496: LDAP Proxy requests memberOf attribute from backend (#1435)
a42ffc3a1 is described below

commit a42ffc3a1313ecdd440a4caf32b6ef2fd4b5fd63
Author: David Han <ha...@users.noreply.github.com>
AuthorDate: Wed Sep 30 04:03:58 2026 -0500

    KNOX-3496: LDAP Proxy requests memberOf attribute from backend (#1435)
---
 .../services/ldap/backend/LdapProxyBackend.java    |  6 +-
 .../ldap/backend/LdapProxyBackendTest.java         | 70 ++++++++++++----------
 2 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackend.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackend.java
index becab28bc..8b5c78950 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackend.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackend.java
@@ -77,6 +77,9 @@ import java.util.stream.Collectors;
 public class LdapProxyBackend implements LdapBackend {
     private static final LdapMessages LOG = MessagesFactory.get(LdapMessages.class);
 
+    private static final String[] ALL_ATTRIBUTES = new String[]{"*"};
+    private static final String[] ALL_ATTRIBUTES_AND_MEMBEROF = new String[]{"*", "memberOf"};
+
     static final String TYPE = "ldap";
 
     private String name;
@@ -561,7 +564,8 @@ public class LdapProxyBackend implements LdapBackend {
         try {
             connection = getConnection();
             List<Entry> results = new ArrayList<>();
-            List<Entry> searchResults = performPagedSearch(connection, remoteSearchBase, remoteFilter, searchScope, "*");
+            String[] attributes = useMemberOf ? ALL_ATTRIBUTES_AND_MEMBEROF : ALL_ATTRIBUTES;
+            List<Entry> searchResults = performPagedSearch(connection, remoteSearchBase, remoteFilter, searchScope, attributes);
             for (Entry entry : searchResults) {
                 addGroupMemberships(entry, connection, entryCache, resolvedParentsCache);
                 results.add(remoteSchemaConverter.convertRemoteEntryToProxyEntry(entry, schemaManager));
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackendTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackendTest.java
index d4bbf1a62..4bb873c76 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackendTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/ldap/backend/LdapProxyBackendTest.java
@@ -74,6 +74,7 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 public class LdapProxyBackendTest {
     private static final int PAGE_SIZE = 2;
@@ -299,11 +300,7 @@ public class LdapProxyBackendTest {
 
         List<String> userGroups = ldapProxyBackend.getUserGroups("ldaptest1", schemaManager);
         assertEquals(3, userGroups.size());
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=groups,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("ldaptest1"))
-                .count();
-        assertEquals(2, matchingRequests);
+        assertEquals(2, findSearchRequests("ou=groups,dc=hadoop,dc=apache,dc=org", "ldaptest1").size());
     }
 
     @Test
@@ -315,11 +312,7 @@ public class LdapProxyBackendTest {
 
         List<String> userGroups = ldapProxyBackend.getUserGroups("ldaptest1", schemaManager);
         assertEquals(PAGE_SIZE, userGroups.size()); // only retrieve 1 page because that will exceed the maxResultSetSize
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=groups,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("ldaptest1"))
-                .count();
-        assertEquals(1, matchingRequests);
+        assertEquals(1, findSearchRequests("ou=groups,dc=hadoop,dc=apache,dc=org", "ldaptest1").size());
     }
 
     @Test
@@ -408,11 +401,7 @@ public class LdapProxyBackendTest {
         config.put("pageSize", Integer.toString(PAGE_SIZE));
         ldapProxyBackend = new LdapProxyBackend("testbackend", config);
         validateUserSearch("*", 4, Set.of("ldaptest1", "ldaptest2", "ldapmemberof", "guest"));
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=people,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("uid=*"))
-                .count();
-        assertEquals(2, matchingRequests);
+        assertEquals(2, findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "uid=*").size());
     }
 
     @Test
@@ -424,11 +413,7 @@ public class LdapProxyBackendTest {
 
         List<Entry> entries = ldapProxyBackend.searchUsers("*", schemaManager);
         assertEquals(PAGE_SIZE, entries.size()); // only expect 1 page of results
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=people,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("uid=*"))
-                .count();
-        assertEquals(1, matchingRequests);
+        assertEquals(1, findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "uid=*").size());
     }
 
     @Test
@@ -577,11 +562,7 @@ public class LdapProxyBackendTest {
         config.put("pageSize", Integer.toString(PAGE_SIZE));
         ldapProxyBackend = new LdapProxyBackend("testbackend", config);
         validateSearch("ou=people,dc=hadoop,dc=apache,dc=org", "(uid=*)", 4, Set.of("ldaptest1", "ldaptest2", "ldapmemberof", "guest"));
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=people,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("uid=*"))
-                .count();
-        assertEquals(2, matchingRequests);
+        assertEquals(2, findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "uid=*").size());
     }
 
     @Test
@@ -592,11 +573,7 @@ public class LdapProxyBackendTest {
         ldapProxyBackend = new LdapProxyBackend("testbackend", config);
         List<Entry> entries = ldapProxyBackend.search("ou=people,dc=hadoop,dc=apache,dc=org", SearchScope.SUBTREE, "(uid=*)", schemaManager);
         assertEquals(PAGE_SIZE, entries.size()); // only expect 1 page because that will exceed the maxResultSetSize
-        int matchingRequests = (int) capturingSearchRequestHandler.getRequests().stream()
-                .filter(request -> request.getBase().getName().equals("ou=people,dc=hadoop,dc=apache,dc=org") &&
-                        request.getFilter().toString().contains("uid=*"))
-                .count();
-        assertEquals(1, matchingRequests);
+        assertEquals(1, findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "uid=*").size());
     }
 
     @Test
@@ -635,6 +612,32 @@ public class LdapProxyBackendTest {
         validateSearch("dc=hadoop,dc=apache,dc=org", "(|(uid=ldap*)(cn=group*))", 6, Set.of("ldaptest1", "ldaptest2", "ldapmemberof", "group1", "group2", "group3"));
     }
 
+    @Test
+    public void testSearchRequestsMemberOfAttributeWhenUseMemberOfEnabled() throws Exception {
+        Map<String, String> config = new HashMap<>(ldapBackendConfig);
+        config.put("useMemberOf", "true");
+        ldapProxyBackend = new LdapProxyBackend("testbackend", config);
+
+        ldapProxyBackend.search("ou=people,dc=hadoop,dc=apache,dc=org", SearchScope.SUBTREE, "(uid=ldaptest1)", schemaManager);
+
+        List<SearchRequest> requests = findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "ldaptest1");
+        assertEquals("Expect exactly 1 matching request found", 1, requests.size());
+        assertTrue("memberOf must be explicitly requested when useMemberOf is enabled",
+                requests.get(0).getAttributes().contains("memberOf"));
+    }
+
+    @Test
+    public void testSearchDoesNotRequestMemberOfAttributeWhenUseMemberOfDisabled() throws Exception {
+        ldapProxyBackend = new LdapProxyBackend("testbackend", ldapBackendConfig);
+
+        ldapProxyBackend.search("ou=people,dc=hadoop,dc=apache,dc=org", SearchScope.SUBTREE, "(uid=ldaptest1)", schemaManager);
+
+        List<SearchRequest> requests = findSearchRequests("ou=people,dc=hadoop,dc=apache,dc=org", "ldaptest1");
+        assertEquals("Expect exactly 1 matching request found", 1, requests.size());
+        assertFalse("memberOf should not be explicitly requested when useMemberOf is disabled",
+                requests.get(0).getAttributes().contains("memberOf"));
+    }
+
     @Test
     public void testSearchRecursiveUserGroupsDepth2() throws Exception {
         Map<String, String> config = createRecursiveConfig(2);
@@ -965,6 +968,13 @@ public class LdapProxyBackendTest {
         }
     }
 
+    private List<SearchRequest> findSearchRequests(String base, String filterContains) {
+        return capturingSearchRequestHandler.getRequests().stream()
+                .filter(request -> request.getBase().getName().equals(base) &&
+                        request.getFilter().toString().contains(filterContains))
+                .collect(Collectors.toList());
+    }
+
     private void testSearchUsersRecursiveWithSharedGroups(Callable<List<Entry>> ldapSearch) throws Exception {
         Map<String, String> config = createRecursiveConfig(5);
         Set<String> expectedGroups = Set.of(