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
|
return result
|
||||||
|
|
||||||
def find_users(self, criteria, sattrs=None):
|
def find_users(self, criteria, sattrs=None):
|
||||||
"""Find users whose uid matches the criteria. Wildcards are
|
"""Return a list: counter followed by a User object for each user that
|
||||||
acceptable. Returns a list of User objects."""
|
matches the criteria. If the results are truncated, counter will
|
||||||
|
be set to -1"""
|
||||||
result = self.transport.find_users(criteria, sattrs)
|
result = self.transport.find_users(criteria, sattrs)
|
||||||
|
counter = result[0]
|
||||||
|
|
||||||
users = []
|
users = [counter]
|
||||||
for attrs in result:
|
for attrs in result[1:]:
|
||||||
if attrs is not None:
|
if attrs is not None:
|
||||||
users.append(user.User(attrs))
|
users.append(user.User(attrs))
|
||||||
|
|
||||||
|
@ -151,8 +151,9 @@ class RPCClient:
|
|||||||
return ipautil.unwrap_binary_data(result)
|
return ipautil.unwrap_binary_data(result)
|
||||||
|
|
||||||
def find_users (self, criteria, sattrs=None):
|
def find_users (self, criteria, sattrs=None):
|
||||||
"""Return a list containing a User object for each user that matches
|
"""Return a list: counter followed by a User object for each user that
|
||||||
the criteria."""
|
matches the criteria. If the results are truncated, counter will
|
||||||
|
be set to -1"""
|
||||||
|
|
||||||
server = self.setup_server()
|
server = self.setup_server()
|
||||||
try:
|
try:
|
||||||
|
@ -140,10 +140,16 @@ class Root(controllers.RootController):
|
|||||||
def userlist(self, **kw):
|
def userlist(self, **kw):
|
||||||
"""Retrieve a list of all users and display them in one huge list"""
|
"""Retrieve a list of all users and display them in one huge list"""
|
||||||
users = None
|
users = None
|
||||||
|
counter = 0
|
||||||
uid = kw.get('uid')
|
uid = kw.get('uid')
|
||||||
if uid != None and len(uid) > 0:
|
if uid != None and len(uid) > 0:
|
||||||
try:
|
try:
|
||||||
users = client.find_users(uid.encode('utf-8'))
|
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:
|
except ipaerror.IPAError, e:
|
||||||
turbogears.flash("User list failed: " + str(e))
|
turbogears.flash("User list failed: " + str(e))
|
||||||
raise turbogears.redirect("/userlist")
|
raise turbogears.redirect("/userlist")
|
||||||
|
@ -129,7 +129,7 @@ body {
|
|||||||
#status_block {
|
#status_block {
|
||||||
margin: 0 auto 0.5em auto;
|
margin: 0 auto 0.5em auto;
|
||||||
padding: 15px 10px 15px 55px;
|
padding: 15px 10px 15px 55px;
|
||||||
background: #cec URL('../images/ok.png') left center no-repeat;
|
background: #cec;
|
||||||
border: 1px solid #9c9;
|
border: 1px solid #9c9;
|
||||||
width: 450px;
|
width: 450px;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="search">
|
<div id="search">
|
||||||
<form action="${tg.url('/userlist')}" method="post">
|
<form action="${tg.url('/userlist')}" method="post">
|
||||||
Search by login/name:
|
Search:
|
||||||
<input type="text" name="uid" />
|
<input type="text" name="uid" />
|
||||||
<input type="submit" />
|
<input type="submit" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div py:if='users != None'>
|
<div py:if='users != None'>
|
||||||
<h2>Results</h2>
|
<h2>${len(users)} results returned:</h2>
|
||||||
<table py:if='len(users) > 0' border="1">
|
<table py:if='len(users) > 0' border="1">
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
|
@ -300,6 +300,44 @@ class IPAdmin(SimpleLDAPObject):
|
|||||||
|
|
||||||
return all_users
|
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):
|
def addEntry(self,*args):
|
||||||
"""This wraps the add function. It assumes that the entry is already
|
"""This wraps the add function. It assumes that the entry is already
|
||||||
populated with all of the desired objectclasses and attributes"""
|
populated with all of the desired objectclasses and attributes"""
|
||||||
|
@ -372,9 +372,8 @@ class IPAServer:
|
|||||||
return users
|
return users
|
||||||
|
|
||||||
def find_users (self, criteria, sattrs=None, opts=None):
|
def find_users (self, criteria, sattrs=None, opts=None):
|
||||||
"""Return a list containing a User object for each
|
"""Returns a list: counter followed by the results.
|
||||||
existing user that matches the criteria.
|
If the results are truncated, counter will be set to -1."""
|
||||||
"""
|
|
||||||
global _LDAPPool
|
global _LDAPPool
|
||||||
|
|
||||||
if opts:
|
if opts:
|
||||||
@ -400,25 +399,36 @@ class IPAServer:
|
|||||||
m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn)
|
m1 = _LDAPPool.getConn(self.host,self.port,self.bindca,self.bindcert,self.bindkey,dn)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
exact_results = m1.getList(self.basedn, self.scope,
|
exact_results = m1.getListAsync(self.basedn, self.scope,
|
||||||
exact_match_filter, sattrs)
|
exact_match_filter, sattrs)
|
||||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
exact_results = []
|
exact_results = [0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
partial_results = m1.getList(self.basedn, self.scope,
|
partial_results = m1.getListAsync(self.basedn, self.scope,
|
||||||
partial_match_filter, sattrs)
|
partial_match_filter, sattrs)
|
||||||
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||||
partial_results = []
|
partial_results = [0]
|
||||||
finally:
|
finally:
|
||||||
_LDAPPool.releaseConn(m1)
|
_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
|
# Remove exact matches from the partial_match list
|
||||||
exact_dns = set(map(lambda e: e.dn, exact_results))
|
exact_dns = set(map(lambda e: e.dn, exact_results))
|
||||||
partial_results = filter(lambda e: e.dn not in exact_dns,
|
partial_results = filter(lambda e: e.dn not in exact_dns,
|
||||||
partial_results)
|
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:
|
for u in exact_results + partial_results:
|
||||||
users.append(self.convert_entry(u))
|
users.append(self.convert_entry(u))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user