mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Change user search to be asynchronous.
This way it returns results even if the search times out. The find_users() search now returns a counter as the first result, which is set to -1 if the results are partial.
This commit is contained in:
parent
ef2dc5cefa
commit
e9bd8dee3b
@ -94,12 +94,14 @@ class IPAClient:
|
||||
return result
|
||||
|
||||
def find_users(self, criteria, sattrs=None):
|
||||
"""Find users whose uid matches the criteria. Wildcards are
|
||||
acceptable. Returns a list of User objects."""
|
||||
"""Return a list: counter followed by a User object for each user that
|
||||
matches the criteria. If the results are truncated, counter will
|
||||
be set to -1"""
|
||||
result = self.transport.find_users(criteria, sattrs)
|
||||
counter = result[0]
|
||||
|
||||
users = []
|
||||
for attrs in result:
|
||||
users = [counter]
|
||||
for attrs in result[1:]:
|
||||
if attrs is not None:
|
||||
users.append(user.User(attrs))
|
||||
|
||||
|
@ -151,8 +151,9 @@ class RPCClient:
|
||||
return ipautil.unwrap_binary_data(result)
|
||||
|
||||
def find_users (self, criteria, sattrs=None):
|
||||
"""Return a list containing a User object for each user that matches
|
||||
the criteria."""
|
||||
"""Return a list: counter followed by a User object for each user that
|
||||
matches the criteria. If the results are truncated, counter will
|
||||
be set to -1"""
|
||||
|
||||
server = self.setup_server()
|
||||
try:
|
||||
|
@ -140,10 +140,16 @@ class Root(controllers.RootController):
|
||||
def userlist(self, **kw):
|
||||
"""Retrieve a list of all users and display them in one huge list"""
|
||||
users = None
|
||||
counter = 0
|
||||
uid = kw.get('uid')
|
||||
if uid != None and len(uid) > 0:
|
||||
try:
|
||||
users = client.find_users(uid.encode('utf-8'))
|
||||
counter = users[0]
|
||||
users = users[1:]
|
||||
if counter == -1:
|
||||
turbogears.flash("These results are truncated.\n" +
|
||||
"Please refine your search and try again.")
|
||||
except ipaerror.IPAError, e:
|
||||
turbogears.flash("User list failed: " + str(e))
|
||||
raise turbogears.redirect("/userlist")
|
||||
|
@ -129,7 +129,7 @@ body {
|
||||
#status_block {
|
||||
margin: 0 auto 0.5em auto;
|
||||
padding: 15px 10px 15px 55px;
|
||||
background: #cec URL('../images/ok.png') left center no-repeat;
|
||||
background: #cec;
|
||||
border: 1px solid #9c9;
|
||||
width: 450px;
|
||||
font-size: 120%;
|
||||
|
@ -8,13 +8,13 @@
|
||||
<body>
|
||||
<div id="search">
|
||||
<form action="${tg.url('/userlist')}" method="post">
|
||||
Search by login/name:
|
||||
Search:
|
||||
<input type="text" name="uid" />
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
<div py:if='users != None'>
|
||||
<h2>Results</h2>
|
||||
<h2>${len(users)} results returned:</h2>
|
||||
<table py:if='len(users) > 0' border="1">
|
||||
<tr>
|
||||
<th>
|
||||
|
@ -300,6 +300,44 @@ class IPAdmin(SimpleLDAPObject):
|
||||
|
||||
return all_users
|
||||
|
||||
def getListAsync(self,*args):
|
||||
"""This version performs an asynchronous search, to allow
|
||||
results even if we hit a limit.
|
||||
|
||||
It returns a list: counter followed by the results.
|
||||
If the results are truncated, counter will be set to -1.
|
||||
"""
|
||||
|
||||
sctrl = self.__get_server_controls__()
|
||||
if sctrl is not None:
|
||||
self.set_option(ldap.OPT_SERVER_CONTROLS, sctrl)
|
||||
|
||||
entries = []
|
||||
partial = 0
|
||||
|
||||
try:
|
||||
msgid = self.search_ext(*args)
|
||||
type, result_list = self.result(msgid, 0)
|
||||
while result_list:
|
||||
for result in result_list:
|
||||
entries.append(result)
|
||||
type, result_list = self.result(msgid, 0)
|
||||
except (ldap.ADMINLIMIT_EXCEEDED, ldap.SIZELIMIT_EXCEEDED), e:
|
||||
partial = 1
|
||||
except ldap.LDAPError, e:
|
||||
raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, None, e)
|
||||
|
||||
if not entries:
|
||||
raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND,
|
||||
"no such entry for " + str(args))
|
||||
|
||||
if partial == 1:
|
||||
counter = -1
|
||||
else:
|
||||
counter = len(entries)
|
||||
|
||||
return [counter] + entries
|
||||
|
||||
def addEntry(self,*args):
|
||||
"""This wraps the add function. It assumes that the entry is already
|
||||
populated with all of the desired objectclasses and attributes"""
|
||||
|
@ -372,9 +372,8 @@ class IPAServer:
|
||||
return users
|
||||
|
||||
def find_users (self, criteria, sattrs=None, opts=None):
|
||||
"""Return a list containing a User object for each
|
||||
existing user that matches the criteria.
|
||||
"""
|
||||
"""Returns a list: counter followed by the results.
|
||||
If the results are truncated, counter will be set to -1."""
|
||||
global _LDAPPool
|
||||
|
||||
if opts:
|
||||
@ -400,25 +399,36 @@ class IPAServer:
|
||||
m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn)
|
||||
try:
|
||||
try:
|
||||
exact_results = m1.getList(self.basedn, self.scope,
|
||||
exact_results = m1.getListAsync(self.basedn, self.scope,
|
||||
exact_match_filter, sattrs)
|
||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||
exact_results = []
|
||||
exact_results = [0]
|
||||
|
||||
try:
|
||||
partial_results = m1.getList(self.basedn, self.scope,
|
||||
partial_results = m1.getListAsync(self.basedn, self.scope,
|
||||
partial_match_filter, sattrs)
|
||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||
partial_results = []
|
||||
partial_results = [0]
|
||||
finally:
|
||||
_LDAPPool.releaseConn(m1)
|
||||
|
||||
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)
|
||||
|
||||
users = []
|
||||
if (exact_counter == -1) or (partial_counter == -1):
|
||||
counter = -1
|
||||
else:
|
||||
counter = len(exact_results) + len(partial_results)
|
||||
|
||||
users = [counter]
|
||||
for u in exact_results + partial_results:
|
||||
users.append(self.convert_entry(u))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user