From 160a97bb210add3b954b93d9c0509e562d449100 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 5 May 2014 16:05:28 -0400
Subject: [PATCH] Added filter to UserService.findUserMemberships().

The UserService.findUserMemberships() has been modified to accept
an additional parameter to filter the groups in which the user
is a member. The CLI has been updated accordingly.

Ticket #920
---
 .../src/com/netscape/certsrv/user/UserClient.java  |  4 +--
 .../com/netscape/certsrv/user/UserResource.java    |  1 +
 .../com/netscape/certsrv/usrgrp/IUGSubsystem.java  |  3 ++-
 .../cmstools/user/UserMembershipFindCLI.java       |  9 ++++---
 .../cms/src/com/netscape/cms/realm/PKIRealm.java   |  2 +-
 .../src/org/dogtagpki/server/rest/UserService.java |  7 +++--
 .../com/netscape/cmscore/usrgrp/UGSubsystem.java   | 30 +++++++++++++++++-----
 7 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/user/UserClient.java b/base/common/src/com/netscape/certsrv/user/UserClient.java
index ee9d9095038fff424c8d8cf92deb0c5b9055f5ff..1df42536dec842b5c81864c344c5cca73a01f2b8 100644
--- a/base/common/src/com/netscape/certsrv/user/UserClient.java
+++ b/base/common/src/com/netscape/certsrv/user/UserClient.java
@@ -85,8 +85,8 @@ public class UserClient extends Client {
         client.getEntity(response, Void.class);
     }
 
-    public UserMembershipCollection findUserMemberships(String userID, Integer start, Integer size) {
-        Response response = userClient.findUserMemberships(userID, start, size);
+    public UserMembershipCollection findUserMemberships(String userID, String filter, Integer start, Integer size) {
+        Response response = userClient.findUserMemberships(userID, filter, start, size);
         return client.getEntity(response, UserMembershipCollection.class);
     }
 
diff --git a/base/common/src/com/netscape/certsrv/user/UserResource.java b/base/common/src/com/netscape/certsrv/user/UserResource.java
index 771750f311e50b3dc2c32152886b2aca2d4e094b..8668221572e3e133800c8cca1a8f3ddd07969006 100644
--- a/base/common/src/com/netscape/certsrv/user/UserResource.java
+++ b/base/common/src/com/netscape/certsrv/user/UserResource.java
@@ -104,6 +104,7 @@ public interface UserResource {
     @ClientResponseType(entityType=UserMembershipCollection.class)
     public Response findUserMemberships(
             @PathParam("userID") String userID,
+            @QueryParam("filter") String filter,
             @QueryParam("start") Integer start,
             @QueryParam("size") Integer size);
 
diff --git a/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java b/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
index cee882a655f65c3d334f06937e12cc77df369d9e..4704f1d9391f5f62482b4193b54fef6ba013f9b1 100644
--- a/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
+++ b/base/common/src/com/netscape/certsrv/usrgrp/IUGSubsystem.java
@@ -132,10 +132,11 @@ public interface IUGSubsystem extends ISubsystem, IUsrGrp {
      * Finds groups that contain the user.
      *
      * @param userDn the user DN
+     * @param filter the search filter
      * @return a list of groups that contain the given user
      * @throws EUsrGrpException
      */
-    public Enumeration<IGroup> findGroupsByUser(String userDn) throws EUsrGrpException;
+    public Enumeration<IGroup> findGroupsByUser(String userDn, String filter) throws EUsrGrpException;
 
     /**
      * Find a group for the given name
diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserMembershipFindCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserMembershipFindCLI.java
index 011c77f1140039fa20acfe71d843a9921e514459..037e45e1cddb243fa64618503da2f97c434ee1ee 100644
--- a/base/java-tools/src/com/netscape/cmstools/user/UserMembershipFindCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/user/UserMembershipFindCLI.java
@@ -44,7 +44,7 @@ public class UserMembershipFindCLI extends CLI {
     }
 
     public void printHelp() {
-        formatter.printHelp(getFullName() + " <User ID> [OPTIONS...]", options);
+        formatter.printHelp(getFullName() + " <User ID> [FILTER] [OPTIONS...]", options);
     }
 
     public void createOptions() {
@@ -78,13 +78,14 @@ public class UserMembershipFindCLI extends CLI {
 
         String[] cmdArgs = cmd.getArgs();
 
-        if (cmdArgs.length != 1) {
-            System.err.println("Error: No User ID specified.");
+        if (cmdArgs.length < 1 || cmdArgs.length > 2) {
+            System.err.println("Error: Incorrect number of arguments specified.");
             printHelp();
             System.exit(-1);
         }
 
         String userID = cmdArgs[0];
+        String filter = cmdArgs.length < 2 ? null : cmdArgs[1];
 
         String s = cmd.getOptionValue("start");
         Integer start = s == null ? null : Integer.valueOf(s);
@@ -92,7 +93,7 @@ public class UserMembershipFindCLI extends CLI {
         s = cmd.getOptionValue("size");
         Integer size = s == null ? null : Integer.valueOf(s);
 
-        UserMembershipCollection response = userMembershipCLI.userClient.findUserMemberships(userID, start, size);
+        UserMembershipCollection response = userMembershipCLI.userClient.findUserMemberships(userID, filter, start, size);
 
         MainCLI.printMessage(response.getTotal() + " entries matched");
         if (response.getTotal() == 0) return;
diff --git a/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java b/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java
index 5ad956157eafca30aeb6772953d898a47fad8425..bd64de148cfd1fc5db759aa23e685eea3a4963a8 100644
--- a/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java
+++ b/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java
@@ -128,7 +128,7 @@ public class PKIRealm extends RealmBase {
         List<String> roles = new ArrayList<String>();
 
         IUGSubsystem ugSub = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
-        Enumeration<IGroup> groups = ugSub.findGroupsByUser(user.getUserDN());
+        Enumeration<IGroup> groups = ugSub.findGroupsByUser(user.getUserDN(), null);
 
         logDebug("Roles:");
         while (groups.hasMoreElements()) {
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/UserService.java b/base/server/cms/src/org/dogtagpki/server/rest/UserService.java
index e8dfaf199d6ded0b80f9847a839d101dcb815537..f4d7a13c58834f1c837309c9d7b850db66e018b8 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/UserService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/UserService.java
@@ -1049,7 +1049,10 @@ public class UserService extends PKIService implements UserResource {
     }
 
     @Override
-    public Response findUserMemberships(String userID, Integer start, Integer size) {
+    public Response findUserMemberships(String userID, String filter, Integer start, Integer size) {
+
+        CMS.debug("UserService.findUserMemberships(" + userID + ", " + filter + ")");
+
         try {
             start = start == null ? 0 : start;
             size = size == null ? DEFAULT_SIZE : size;
@@ -1066,7 +1069,7 @@ public class UserService extends PKIService implements UserResource {
                 throw new UserNotFoundException(userID);
             }
 
-            Enumeration<IGroup> groups = userGroupManager.findGroupsByUser(user.getUserDN());
+            Enumeration<IGroup> groups = userGroupManager.findGroupsByUser(user.getUserDN(), filter);
 
             UserMembershipCollection response = new UserMembershipCollection();
             int i = 0;
diff --git a/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
index 5d7d773fd75b7133b59310040a6436754dd66b4a..245115e755a735efeabcc7bb082f6d882159832e 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/usrgrp/UGSubsystem.java
@@ -1421,34 +1421,52 @@ public final class UGSubsystem implements IUGSubsystem {
         return null;
     }
 
-    public Enumeration<IGroup> findGroupsByUser(String userDn) throws EUsrGrpException {
+    public Enumeration<IGroup> findGroupsByUser(String userDn, String filter) throws EUsrGrpException {
+
         if (userDn == null) {
             return null;
         }
 
+        // search groups where the user is a member
+        String ldapFilter = "(&(objectclass=groupofuniquenames)(uniqueMember=" + LDAPUtil.escapeFilter(userDn) + ")";
+
+        if (!StringUtils.isEmpty(filter)) {
+            // combine search filter if specified
+            filter = LDAPUtil.escapeFilter(filter);
+            ldapFilter += "(cn=*" + filter + "*)";
+        }
+
+        ldapFilter += ")";
+
         LDAPConnection ldapconn = null;
 
         try {
             String attrs[] = new String[2];
-
             attrs[0] = "cn";
             attrs[1] = "description";
 
             ldapconn = getConn();
-            LDAPSearchResults res =
-                    ldapconn.search(getGroupBaseDN(), LDAPv2.SCOPE_SUB,
-                            "(&(objectclass=groupofuniquenames)(uniqueMember=" + LDAPUtil.escapeFilter(userDn) + "))",
-                            attrs, false);
+
+            LDAPSearchResults res = ldapconn.search(
+                    getGroupBaseDN(),
+                    LDAPv2.SCOPE_ONE,
+                    ldapFilter,
+                    attrs,
+                    false);
 
             return buildGroups(res);
+
         } catch (LDAPException e) {
             log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_GROUPS", e.toString()));
+
         } catch (ELdapException e) {
             log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_USRGRP_LIST_GROUPS", e.toString()));
+
         } finally {
             if (ldapconn != null)
                 returnConn(ldapconn);
         }
+
         return null;
     }
 
-- 
1.8.4.2

