Skip to content

Commit 3bb30ac

Browse files
committed
MiscUtil: CERN LDAP plugin improvement
* Improves the search function and introduces paged search to avoid exceeding the size limit of the CERN LDAP server. Signed-off-by: Jochen Klein <j.klein@cern.ch>
1 parent c3e2911 commit 3bb30ac

1 file changed

Lines changed: 48 additions & 9 deletions

File tree

modules/miscutil/lib/ldap_cern.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## This file is part of Invenio.
2-
## Copyright (C) 2009, 2010, 2011, 2014 CERN.
2+
## Copyright (C) 2009, 2010, 2011, 2014, 2015 CERN.
33
##
44
## Invenio is free software; you can redistribute it and/or
55
## modify it under the terms of the GNU General Public License as
@@ -22,9 +22,11 @@
2222

2323
import ldap
2424
import ldap.filter
25+
from ldap.controls import SimplePagedResultsControl
2526

2627
CFG_CERN_LDAP_URI = "ldap://xldap.cern.ch:389"
2728
CFG_CERN_LDAP_BASE = "OU=Users,OU=Organic Units,DC=cern,DC=ch"
29+
CFG_CERN_LDAP_PAGESIZE = 250
2830

2931
_ldap_connection_pool = {}
3032

@@ -48,6 +50,47 @@ def _sanitize_input(query):
4850
return query
4951

5052

53+
def _paged_search(ldap_connection, query_filter):
54+
"""
55+
Search the CERN LDAP server.
56+
Return a list of user dictionaries (or empty list).
57+
"""
58+
req_ctrl = SimplePagedResultsControl(True, CFG_CERN_LDAP_PAGESIZE, "")
59+
msgid = ldap_connection.search_ext(
60+
CFG_CERN_LDAP_BASE,
61+
ldap.SCOPE_SUBTREE,
62+
query_filter,
63+
attrlist=None,
64+
attrsonly=0,
65+
serverctrls=[req_ctrl])
66+
result_pages = 0
67+
results = []
68+
69+
while True:
70+
rtype, rdata, rmsgid, rctrls = ldap_connection.result3(msgid)
71+
results.extend(rdata)
72+
result_pages += 1
73+
74+
pctrls = [
75+
c
76+
for c in rctrls
77+
if c.controlType == SimplePagedResultsControl.controlType
78+
]
79+
if pctrls:
80+
if pctrls[0].cookie:
81+
req_ctrl.cookie = pctrls[0].cookie
82+
msgid = ldap_connection.search_ext(
83+
CFG_CERN_LDAP_BASE,
84+
ldap.SCOPE_SUBTREE,
85+
query_filter,
86+
attrlist=None,
87+
attrsonly=0,
88+
serverctrls=[req_ctrl])
89+
else:
90+
break
91+
return results
92+
93+
5194
def get_users_info_by_displayName(displayName):
5295
"""
5396
Query the CERN LDAP server for information about all users whose name
@@ -71,15 +114,13 @@ def get_users_info_by_displayName(displayName):
71114
return []
72115

73116
try:
74-
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
75-
query_filter, timeout=5)
117+
results = _paged_search(connection, query_filter)
76118
except ldap.LDAPError:
77119
## Mmh.. connection error? Let's reconnect at least once just in case
78120
sleep(1)
79121
connection = _cern_ldap_login()
80122
try:
81-
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
82-
query_filter, timeout=5)
123+
results = _paged_search(connection, query_filter)
83124
except ldap.LDAPError:
84125
# Another error (maybe the LDAP query size is too big, etc.)
85126
# TODO, if it's needed, here we can return various different
@@ -114,15 +155,13 @@ def get_users_info_by_displayName_or_email(name):
114155
return []
115156

116157
try:
117-
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
118-
query_filter, timeout=5)
158+
results = _paged_search(connection, query_filter)
119159
except ldap.LDAPError:
120160
## Mmh.. connection error? Let's reconnect at least once just in case
121161
sleep(1)
122162
connection = _cern_ldap_login()
123163
try:
124-
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
125-
query_filter, timeout=5)
164+
results = _paged_search(connection, query_filter)
126165
except ldap.LDAPError:
127166
# Another error (maybe the LDAP query size is too big, etc.)
128167
# TODO, if it's needed, here we can return various different

0 commit comments

Comments
 (0)