Skip to content

Commit

Permalink
MiscUtil: CERN LDAP plugin improvement
Browse files Browse the repository at this point in the history
* Improves the search function and introduces paged search to
  avoid exceeding the size limit of the CERN LDAP server.

Signed-off-by: Jochen Klein <[email protected]>
  • Loading branch information
jochenklein committed Aug 26, 2015
1 parent c3e2911 commit 3bb30ac
Showing 1 changed file with 48 additions and 9 deletions.
57 changes: 48 additions & 9 deletions modules/miscutil/lib/ldap_cern.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## This file is part of Invenio.
## Copyright (C) 2009, 2010, 2011, 2014 CERN.
## Copyright (C) 2009, 2010, 2011, 2014, 2015 CERN.
##
## Invenio is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
Expand All @@ -22,9 +22,11 @@

import ldap
import ldap.filter
from ldap.controls import SimplePagedResultsControl

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

_ldap_connection_pool = {}

Expand All @@ -48,6 +50,47 @@ def _sanitize_input(query):
return query


def _paged_search(ldap_connection, query_filter):
"""
Search the CERN LDAP server.
Return a list of user dictionaries (or empty list).
"""
req_ctrl = SimplePagedResultsControl(True, CFG_CERN_LDAP_PAGESIZE, "")
msgid = ldap_connection.search_ext(
CFG_CERN_LDAP_BASE,
ldap.SCOPE_SUBTREE,
query_filter,
attrlist=None,
attrsonly=0,
serverctrls=[req_ctrl])
result_pages = 0
results = []

while True:
rtype, rdata, rmsgid, rctrls = ldap_connection.result3(msgid)
results.extend(rdata)
result_pages += 1

pctrls = [
c
for c in rctrls
if c.controlType == SimplePagedResultsControl.controlType
]
if pctrls:
if pctrls[0].cookie:
req_ctrl.cookie = pctrls[0].cookie
msgid = ldap_connection.search_ext(
CFG_CERN_LDAP_BASE,
ldap.SCOPE_SUBTREE,
query_filter,
attrlist=None,
attrsonly=0,
serverctrls=[req_ctrl])
else:
break
return results


def get_users_info_by_displayName(displayName):
"""
Query the CERN LDAP server for information about all users whose name
Expand All @@ -71,15 +114,13 @@ def get_users_info_by_displayName(displayName):
return []

try:
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
query_filter, timeout=5)
results = _paged_search(connection, query_filter)
except ldap.LDAPError:
## Mmh.. connection error? Let's reconnect at least once just in case
sleep(1)
connection = _cern_ldap_login()
try:
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
query_filter, timeout=5)
results = _paged_search(connection, query_filter)
except ldap.LDAPError:
# Another error (maybe the LDAP query size is too big, etc.)
# TODO, if it's needed, here we can return various different
Expand Down Expand Up @@ -114,15 +155,13 @@ def get_users_info_by_displayName_or_email(name):
return []

try:
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
query_filter, timeout=5)
results = _paged_search(connection, query_filter)
except ldap.LDAPError:
## Mmh.. connection error? Let's reconnect at least once just in case
sleep(1)
connection = _cern_ldap_login()
try:
results = connection.search_st(CFG_CERN_LDAP_BASE, ldap.SCOPE_SUBTREE,
query_filter, timeout=5)
results = _paged_search(connection, query_filter)
except ldap.LDAPError:
# Another error (maybe the LDAP query size is too big, etc.)
# TODO, if it's needed, here we can return various different
Expand Down

0 comments on commit 3bb30ac

Please sign in to comment.