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
2222
2323import ldap
2424import ldap .filter
25+ from ldap .controls import SimplePagedResultsControl
2526
2627CFG_CERN_LDAP_URI = "ldap://xldap.cern.ch:389"
2728CFG_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+
5194def 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