diff options
author | Kevin McCarthy <kmccarth@redhat.com> | 2007-09-19 08:42:34 -0700 |
---|---|---|
committer | Kevin McCarthy <kmccarth@redhat.com> | 2007-09-19 08:42:34 -0700 |
commit | f17071533a73c5e989ead1b243de5397d36a38d3 (patch) | |
tree | 6156ae63ae36ede5e601bbf2fcb962783d438094 | |
parent | 6b3d1e85da1397324fa7e8dc25706129ff8ed6fc (diff) | |
download | freeipa-f17071533a73c5e989ead1b243de5397d36a38d3.tar.gz freeipa-f17071533a73c5e989ead1b243de5397d36a38d3.tar.xz freeipa-f17071533a73c5e989ead1b243de5397d36a38d3.zip |
Implement asynchronous search for groups.
Use the filter generation code to search on multiple fields.
-rw-r--r-- | ipa-admintools/ipa-findgroup | 4 | ||||
-rw-r--r-- | ipa-python/ipaclient.py | 9 | ||||
-rw-r--r-- | ipa-python/rpcclient.py | 4 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/controllers.py | 10 | ||||
-rw-r--r-- | ipa-server/xmlrpc-server/funcs.py | 63 |
5 files changed, 70 insertions, 20 deletions
diff --git a/ipa-admintools/ipa-findgroup b/ipa-admintools/ipa-findgroup index 43171e42..92b3b25b 100644 --- a/ipa-admintools/ipa-findgroup +++ b/ipa-admintools/ipa-findgroup @@ -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 --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py index 4e293b01..63537f26 100644 --- a/ipa-python/ipaclient.py +++ b/ipa-python/ipaclient.py @@ -161,13 +161,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) + result = self.transport.find_groups(criteria, sattrs, searchlimit) + counter = result[0] - groups = [] - for attrs in result: + groups = [counter] + for attrs in result[1:]: if attrs is not None: groups.append(group.Group(attrs)) diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py index 96c8976c..9e51e981 100644 --- a/ipa-python/rpcclient.py +++ b/ipa-python/rpcclient.py @@ -259,7 +259,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.""" @@ -268,7 +268,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 --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index dcf65530..7a6d87ff 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -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 --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py index 7d61f130..4e23fde2 100644 --- a/ipa-server/xmlrpc-server/funcs.py +++ b/ipa-server/xmlrpc-server/funcs.py @@ -585,25 +585,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) + 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) - filter = "(&(cn=%s)(objectClass=posixGroup))" % criteria + # + # 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: - results = conn.getList(self.basedn, self.scope, filter, sattrs) - except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND): - results = [] + 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) - groups = [] - for u in results: + 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): |