[Freeipa-devel] [PATCH] group search improvements

Kevin McCarthy kmccarth at redhat.com
Wed Sep 19 15:44:21 UTC 2007


Rob Crittenden wrote:
> Can you see if the command-line ipa-findgroup still works? I think the 
> addition of the counter will break it.

I did forget to update ipa-findgroup (thanks Rob).

Attached is a revised patch including that fix.

-Kevin
-------------- next part --------------
# HG changeset patch
# User Kevin McCarthy <kmccarth at redhat.com>
# Date 1190216554 25200
# Node ID f7e2e4d1ed705049d26e77eab8829af43abe0055
# Parent  88832dc9643b967ffed0aa4377512490accfe0e4
Implement asynchronous search for groups.
Use the filter generation code to search on multiple fields.

diff -r 88832dc9643b -r f7e2e4d1ed70 ipa-admintools/ipa-findgroup
--- a/ipa-admintools/ipa-findgroup	Tue Sep 18 14:58:30 2007 -0700
+++ b/ipa-admintools/ipa-findgroup	Wed Sep 19 08:42:34 2007 -0700
@@ -50,7 +50,9 @@ def main():
         client = ipaclient.IPAClient()
         groups = client.find_groups(args[1])
 
-        if len(groups) == 0:
+        counter = groups[0]
+        groups = groups[1:]
+        if counter == 0:
             print "No entries found for", args[1]
             return 0
 
diff -r 88832dc9643b -r f7e2e4d1ed70 ipa-python/ipaclient.py
--- a/ipa-python/ipaclient.py	Tue Sep 18 14:58:30 2007 -0700
+++ b/ipa-python/ipaclient.py	Wed Sep 19 08:42:34 2007 -0700
@@ -158,13 +158,14 @@ class IPAClient:
         result = self.transport.add_group(group_dict, group_container)
         return result
 
-    def find_groups(self, criteria, sattrs=None):
+    def find_groups(self, criteria, sattrs=None, searchlimit=0):
         """Find groups whose cn matches the criteria. Wildcards are 
            acceptable. Returns a list of Group objects."""
-        result = self.transport.find_groups(criteria, sattrs)
-
-        groups = []
-        for attrs in result:
+        result = self.transport.find_groups(criteria, sattrs, searchlimit)
+        counter = result[0]
+
+        groups = [counter]
+        for attrs in result[1:]:
             if attrs is not None:
                 groups.append(group.Group(attrs))
 
diff -r 88832dc9643b -r f7e2e4d1ed70 ipa-python/rpcclient.py
--- a/ipa-python/rpcclient.py	Tue Sep 18 14:58:30 2007 -0700
+++ b/ipa-python/rpcclient.py	Wed Sep 19 08:42:34 2007 -0700
@@ -275,7 +275,7 @@ class RPCClient:
         except socket.error, (value, msg):
             raise xmlrpclib.Fault(value, msg)
 
-    def find_groups (self, criteria, sattrs=None):
+    def find_groups (self, criteria, sattrs=None, searchlimit=0):
         """Return a list containing a Group object for each group that matches
            the criteria."""
     
@@ -284,7 +284,7 @@ class RPCClient:
             # None values are not allowed in XML-RPC
             if sattrs is None:
                 sattrs = "__NONE__"
-            result = server.find_groups(criteria, sattrs)
+            result = server.find_groups(criteria, sattrs, searchlimit)
         except xmlrpclib.Fault, fault:
             raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
         except socket.error, (value, msg):
diff -r 88832dc9643b -r f7e2e4d1ed70 ipa-server/ipa-gui/ipagui/controllers.py
--- a/ipa-server/ipa-gui/ipagui/controllers.py	Tue Sep 18 14:58:30 2007 -0700
+++ b/ipa-server/ipa-gui/ipagui/controllers.py	Wed Sep 19 08:42:34 2007 -0700
@@ -551,11 +551,11 @@ class Root(controllers.RootController):
         if criteria != None and len(criteria) > 0:
             try:
                 groups = client.find_groups(criteria.encode('utf-8'))
-                # counter = groups[0]
-                # groups = groups[1:]
-                # if counter == -1:
-                #     turbogears.flash("These results are truncated.<br />" +
-                #                     "Please refine your search and try again.")
+                counter = groups[0]
+                groups = groups[1:]
+                if counter == -1:
+                    turbogears.flash("These results are truncated.<br />" +
+                                    "Please refine your search and try again.")
             except ipaerror.IPAError, e:
                 turbogears.flash("Find groups failed: " + str(e))
                 raise turbogears.redirect("/grouplist")
diff -r 88832dc9643b -r f7e2e4d1ed70 ipa-server/xmlrpc-server/funcs.py
--- a/ipa-server/xmlrpc-server/funcs.py	Tue Sep 18 14:58:30 2007 -0700
+++ b/ipa-server/xmlrpc-server/funcs.py	Wed Sep 19 08:42:34 2007 -0700
@@ -603,25 +603,72 @@ class IPAServer:
         finally:
             self.releaseConnection(conn)
 
-    def find_groups (self, criteria, sattrs=None, opts=None):
+    def find_groups (self, criteria, sattrs=None, searchlimit=0, opts=None):
         """Return a list containing a User object for each
         existing group that matches the criteria.
         """
+        # Assume the list of fields to search will come from a central
+        # configuration repository.  A good format for that would be
+        # a comma-separated list of fields
+        search_fields_conf_str = "cn,description"
+        search_fields = string.split(search_fields_conf_str, ",")
+
         criteria = self.__safe_filter(criteria)
-
-        filter = "(&(cn=%s)(objectClass=posixGroup))" % criteria
-        conn = self.getConnection(opts)
-        try:
-            results = conn.getList(self.basedn, self.scope, filter, sattrs)
-        except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
-            results = []
-        finally:
-            self.releaseConnection(conn)
-
-        groups = []
-        for u in results:
+        criteria_words = re.split(r'\s+', criteria)
+        criteria_words = filter(lambda value:value!="", criteria_words)
+        if len(criteria_words) == 0:
+            return [0]
+
+        (exact_match_filter, partial_match_filter) = self.__generate_match_filters(
+                search_fields, criteria_words)
+
+        #
+        # further constrain search to just the objectClass
+        # TODO - need to parameterize this into generate_match_filters,
+        #        and work it into the field-specification search feature
+        #
+        exact_match_filter = "(&(objectClass=posixGroup)%s)" % exact_match_filter
+        partial_match_filter = "(&(objectClass=posixGroup)%s)" % partial_match_filter
+
+        #
+        # TODO - copy/paste from find_users.  needs to be refactored
+        #
+        conn = self.getConnection(opts)
+        try:
+            try:
+                exact_results = conn.getListAsync(self.basedn, self.scope,
+                        exact_match_filter, sattrs, 0, None, None, -1, searchlimit)
+            except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
+                exact_results = [0]
+
+            try:
+                partial_results = conn.getListAsync(self.basedn, self.scope,
+                        partial_match_filter, sattrs, 0, None, None, -1, searchlimit)
+            except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
+                partial_results = [0]
+        finally:
+            self.releaseConnection(conn)
+
+        exact_counter = exact_results[0]
+        partial_counter = partial_results[0]
+
+        exact_results = exact_results[1:]
+        partial_results = partial_results[1:]
+
+        # Remove exact matches from the partial_match list
+        exact_dns = set(map(lambda e: e.dn, exact_results))
+        partial_results = filter(lambda e: e.dn not in exact_dns,
+                                 partial_results)
+
+        if (exact_counter == -1) or (partial_counter == -1):
+            counter = -1
+        else:
+            counter = len(exact_results) + len(partial_results)
+
+        groups = [counter]
+        for u in exact_results + partial_results:
             groups.append(self.convert_entry(u))
-    
+
         return groups
 
     def add_user_to_group(self, user, group, opts=None):
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 2228 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/freeipa-devel/attachments/20070919/73eff35a/attachment.bin>


More information about the Freeipa-devel mailing list