From 33e6507a25f8330b8f5bcfb2f98634657c745cea Mon Sep 17 00:00:00 2001 From: Dan Scott Date: Wed, 7 Sep 2011 11:34:04 -0400 Subject: [PATCH] Getting LDAP synchronization production ready * Search for user before attempting to create the user * Set the default expiry date by profile * Document how we're currently populating barcodes Signed-off-by: Dan Scott --- tools/patron-load/ldap_osrf_sync | 130 +++++++++++++++++++++++++++++++++------ 1 file changed, 112 insertions(+), 18 deletions(-) diff --git a/tools/patron-load/ldap_osrf_sync b/tools/patron-load/ldap_osrf_sync index 8786add17f..5110a9f7b7 100644 --- a/tools/patron-load/ldap_osrf_sync +++ b/tools/patron-load/ldap_osrf_sync @@ -10,11 +10,26 @@ file (credentials.py) and imported to avoid storing credentials in the VCS. directory using the filter (createTimestamp>=time). 2. For each new LDAP record, check to see if the record exists in Evergreen - (matching on ident_value) + (matching on ident_value, usrname, email). If not, create a new account with barcode. -3. Dump the output of new ident_value + barcode in CSV format somewhere. +3. Push the new barcode back into the LDAP directory. + +Needs to be able to find credentials.py with the following content: + +LDAP_HOST = 'ldap://192.168.1.106' +LDAP_DN = 'cn=ldap_usr' +LDAP_PW = 'password' + +OSRF_HTTP = 'http' +IDL_URL = '/reports/fm_IDL.xml' +GATEWAY_URL = '/osrf-gateway-v1' + +OSRF_HOST = 'localhost' +OSRF_USER = 'admin' +OSRF_PW = 'demo123' +OSRF_WORK_OU = 'herb' """ import os @@ -72,6 +87,20 @@ class User: print >> sys.stderr, 'No givenName for %s' % (self.usrname) self.profile = self.get_profile() + self.expire_date = self.get_expiry_date() + + def get_expiry_date(self): + """ + Map LDAP record to Evergreen expiry dates + """ + + # Faculty and staff get a long time + if self.profile == 11 or self.profile == 14: + return '2020-09-30' + elif self.profile == 13 or self.profile == 12: + # Students get next academic year + return '2012-09-30' + return '2012-09-30' def get_identity(self): """ @@ -288,8 +317,8 @@ def find_new_ldap_users(con, attributes, create_date, auth): base_dn = 'o=lul' search_scope = ldap.SCOPE_SUBTREE ldap_filter = '(&(objectclass=lulEduPerson))' - ldap_filter = '(&(objectclass=lulEduPerson)(lulPrimaryAffiliation=*)(createTimestamp>=%s000000Z))' % create_date ldap_filter = '(&(lulStudentLevel=*))' + ldap_filter = '(&(objectclass=lulEduPerson)(lulPrimaryAffiliation=*)(createTimestamp>=%s))' % create_date try: result_id = con.search(base_dn, search_scope, ldap_filter, attributes) @@ -299,11 +328,54 @@ def find_new_ldap_users(con, attributes, create_date, auth): break else: # dump_data(result_data) - create_evergreen_user(result_data[0][1], auth) + create_evergreen_user(auth, result_data[0][1]) except ldap.LDAPError, exc: print >> sys.stderr, exc -def create_evergreen_user(result_data, auth): +def find_evergreen_user(auth, user): + """ + Search for an existing user in Evergreen + + Returns True if found, False if not + """ + + limit = 1 + sort = None + search_ou = 1 + include_inactive = True + + print("Trying to find user: %s %s %s" % + (user.ident_value, user.email, user.usrname) + ) + + by_id = osrf_request( + 'open-ils.actor', 'open-ils.actor.patron.search.advanced', + auth, {'ident_value': {'value': user.ident_value, 'group': 0}}, limit, + sort, include_inactive, search_ou + ).send() + + if by_id and len(by_id): + return True + + by_email = osrf_request( + 'open-ils.actor', 'open-ils.actor.patron.search.advanced', + auth, {'email': {'value': user.email}}, limit, + sort, include_inactive, search_ou + ).send() + + if by_email and len(by_email): + return True + + by_usrname = osrf_request( + 'open-ils.actor', 'open-ils.actor.patron.search.advanced', + auth, {'usrname': {'value': user.usrname}}, limit, + sort, include_inactive, search_ou + ).send() + + if by_usrname and len(by_usrname): + return True + +def create_evergreen_user(auth, result_data): """ Map LDAP record to Evergreen user """ @@ -312,6 +384,11 @@ def create_evergreen_user(result_data, auth): if not user: return + found = find_evergreen_user(auth, user) + if found: + print("Found: %s" % user.usrname) + return + newau = osrf.net_obj.new_object_from_hint('au') newau.isnew(True) @@ -324,6 +401,11 @@ def create_evergreen_user(result_data, auth): newau.ident_value(user.ident_value) newau.home_ou(user.home_ou) newau.passwd(user.passwd) + newau.expire_date(user.expire_date) + + # Workaround open-ils.actor.patron.update bug + newau.addresses([]) + newau.cards([]) # Create the user try: @@ -339,10 +421,19 @@ def create_evergreen_user(result_data, auth): # XXX Create barcode... how? # Trigger on actor.usr? New custom API? + # Currently doing the horrible thing of: + # SELECT evergreen.lu_update_barcode(id) + # FROM actor.usr + # WHERE create_date > %s + # AND barcode IS NULL + # AND home_ou IN ( + # SELECT id FROM actor.org_unit WHERE parent_ou = 105 + # ) + # ; create_stat_cats(newau, result_data) - print(newau) + print("Created: %s" % newau.usrname()) def create_stat_cats(user, result_data): """ @@ -403,17 +494,20 @@ if __name__ == '__main__': load_idl() # Log in and get an authtoken - AUTHTOKEN = osrf_login(credentials.OSRF_USER, credentials.OSRF_PW) - - UDATA = { - 'mail': ['dan@example.com'], - 'givenName': ['Dan'], - 'sn': ['Scott'], - 'lulColleagueId': ['0123456'], - 'lulStudentLevel': ['GR'], - } - create_evergreen_user(UDATA, AUTHTOKEN) - -# ldap_create_by_date('20110701') + AUTHTOKEN = osrf_login( + credentials.OSRF_USER, credentials.OSRF_PW, credentials.OSRF_WORK_OU + ) + +# UDATA = { +# 'mail': ['dan@example.com'], +# 'givenName': ['Dan'], +# 'sn': ['Scott'], +# 'lulColleagueId': ['0123456'], +# 'lulStudentLevel': ['GR'], +# } +# create_evergreen_user(AUTHTOKEN, UDATA) + + # XXX Pull this in from sys.argv + ldap_create_by_date('20110906130000Z', AUTHTOKEN) # vim: et:ts=4:sw=4:tw=78: -- 2.11.0