1. Johnny Goodnow
  2. hokiefinder

Source

hokiefinder / geolocator / ldap_reader.py

import ldap
from ldap.controls import SimplePagedResultsControl

class Ldap_Reader:
    url = 'ldap://directory.vt.edu'
    basedn = 'ou=People,dc=vt,dc=edu'
    page_size = 100

    def __init__(self, search_key, search_value):
        self.con = ldap.initialize(self.__class__.url)
        self.con.protocol_version = 3
        self.con.simple_bind_s()
    
        self.control = SimplePagedResultsControl(
            ldap.LDAP_CONTROL_PAGE_OID, True, (self.__class__.page_size, '')
        )
        if search_key == 'uupid':
            self.search_filter = r'(&(localPostalAddress=*)(uupid=*' + search_value + '*))'
        elif search_key == 'displayName':
            self.search_filter = r'(&(localPostalAddress=*)(displayName=*' + search_value + '*))'
        elif search_key == 'major':
            self.search_filter = r'(&(localPostalAddress=*)(major=*' + search_value + '*))'
        else:
            raise ValueError('Searched by an unsupported key')    

        self.msgid = self.con.search_ext(
            self.__class__.basedn,
            ldap.SCOPE_SUBTREE,
            self.search_filter,
            serverctrls=[self.control]
        )

    def get(self):
        rtype, rdata, rmsgid, serverctrls = self.con.result3(self.msgid)
        pctrls = [c for c in serverctrls if c.controlType == ldap.LDAP_CONTROL_PAGE_OID]
        if pctrls:
            est, cookie = pctrls[0].controlValue
            if cookie:
                self.control.controlValue = (self.__class__.page_size, cookie)
                self.msgid = self.con.search_ext(
                    self.__class__.basedn,
                    ldap.SCOPE_SUBTREE,
                    self.search_filter,
                    serverctrls=[self.control],
                    )
        else:
            raise Warning("Warning:  Server ignores RFC 2696 control.")
        for person in rdata:
            info = person[1]
            if 'localPostalAddress' in info:
                info['localPostalAddress'][0] = info['localPostalAddress'][0].replace('$',',')

        return rdata

    def close(self):
        self.con.unbind()