From 8f98b5349a06acc0edcb6250c39c7bb3379992b2 Mon Sep 17 00:00:00 2001 From: Dan Scott Date: Thu, 8 Sep 2011 17:26:58 -0400 Subject: [PATCH] Generate barcodes and push them into LDAP Add a custom API to open-ils.actor for generating barcodes; accepts one argument, user ID, which gets the barcode set to their new value. If no arg is passed, just generates a new barcode and returns it (should be useful on the patron editor screen). As far as pushing the barcodes into LDAP goes, I can't confirm that the updates are actually working, because I can't see them, but the lack of errors suggests that it's working. Signed-off-by: Dan Scott --- .../src/perlmods/lib/OpenILS/Application/Actor.pm | 39 +++++ tools/patron-load/ldap_osrf_sync | 184 +++++++++++++-------- 2 files changed, 155 insertions(+), 68 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm index 570d332c97..4b1619c052 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm @@ -4293,6 +4293,45 @@ sub user_saved_search_cud { return $res; } +__PACKAGE__->register_method( + method => "generate_patron_barcode", + api_name => "open-ils.actor.generate_patron_barcode", + signature => { + desc => "Generates a new patron barcode. If a user ID is supplied," . + "that user's card will be updated to point at the new barcode." , + params => [ + {desc => 'Authentication token', type => 'string'}, + {desc => 'User ID', type => 'number'}, + ], + return => {desc => 'Generated barcode on success'} + } +); + +# evergreen.lu_update_barcode(user-id) generates a barcode, creates an actor.card +# object, and points actor.usr.card to the new actor.card.id +# +# evergreen.lu_generate_barcode() just generates a barcode +sub generate_patron_barcode { + + my( $self, $client, $auth, $user_id ) = @_; + + my $e = new_editor( authtoken=>$auth ); + return $e->die_event unless $e->checkauth; + + my $barcode; + if ($user_id) { + return $e->die_event unless $e->allowed('UPDATE_USER'); + $barcode = $e->json_query( + {from => ['evergreen.lu_update_barcode', $user_id]})->[0] + or return $e->die_event; + } else { + $barcode = $e->json_query( + {from => ['evergreen.lu_generate_barcode']})->[0] + or return $e->die_event; + } + + return $barcode; +} 1; diff --git a/tools/patron-load/ldap_osrf_sync b/tools/patron-load/ldap_osrf_sync index c60d3f96d3..f305d14e4e 100644 --- a/tools/patron-load/ldap_osrf_sync +++ b/tools/patron-load/ldap_osrf_sync @@ -332,18 +332,20 @@ def find_ldap_users(con, ldap_filter, attributes, auth): base_dn = 'o=lul' search_scope = ldap.SCOPE_SUBTREE - print ldap_filter try: result_id = con.search(base_dn, search_scope, ldap_filter, attributes) while 1: result_type, result_data = con.result(result_id, 0) if result_data == []: break - else: - if ARGS.dump_ldap: - dump_data(result_data) - if ARGS.create_users: - create_evergreen_user(auth, result_data[0][1]) + + if ARGS.dump_ldap: + dump_data(result_data) + if ARGS.create_users: + (ident, code) = create_evergreen_user(auth, result_data[0][1]) + # Push the barcode into LDAP + update_ldap_barcode(con, ident, code) + except ldap.LDAPError, exc: print >> sys.stderr, exc @@ -424,31 +426,68 @@ def create_evergreen_user(auth, result_data): # Create the user try: - result = osrf_request( + usr = osrf_request( 'open-ils.actor', 'open-ils.actor.patron.update', auth, newau ).send() except Exception, exc: print exc - evt = oils.event.Event.parse_event(result) + evt = oils.event.Event.parse_event(usr) if evt and not evt.success: raise AuthException(evt.text_code) - # 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 - # ) - # ; + # Generate a barcode for the user + try: + barcode = osrf_request( + 'open-ils.actor', 'open-ils.actor.generate_patron_barcode', + auth, usr.id() + ).send() + except Exception, exc: + print exc + + evt = oils.event.Event.parse_event(barcode) + if evt and not evt.success: + raise AuthException(evt.text_code) + + barcode = barcode['evergreen.lu_update_barcode'] create_stat_cats(newau, result_data) - print("Created: %s" % newau.usrname()) + print("Created: %s with barcode %s" % (newau.usrname(), barcode)) + + return (newau.ident_value(), barcode) + +def update_ldap_barcode(con, ident, barcode): + """ + Updates the LDAP directory with the new barcode for a given user + + We need to retrieve the qualified CN for the ldap.modify_s operation, + first, so take the first match we get. Reckless, I know. + """ + + base_dn = 'o=lul' + search_scope = ldap.SCOPE_SUBTREE + + try: + ldap_filter = '(&%s(lulColleagueId=%s))' % ( + '(objectclass=lulEduPerson)', ident + ) + result_id = con.search(base_dn, search_scope, ldap_filter) + while 1: + result_type, result_data = con.result(result_id, 0) + if result_data == []: + break + + if 'lulColleagueId' not in result_data[0][1]: + continue + + cname = result_data[0][1]['cn'][0] + mod_attrs = [(ldap.MOD_REPLACE, 'lulLibraryBarcode', barcode)] + con.modify(cname, mod_attrs) + except Exception, exc: + print >> sys.stderr, exc + + return True def create_stat_cats(user, result_data): """ @@ -473,49 +512,34 @@ def dump_data(result_data): for key in result_data[0][1]: print(key, result_data[0][1][key]) -def ldap_create_by_date(auth): +def ldap_query(con, auth): """ - Connect to LDAP directory and process users created since a given date + Process LDAP users created since a given date """ - - con = ldap.initialize(ARGS.ldap_server) - con.set_option(ldap.OPT_REFERRALS, 0) - - try: - attributes = [ - 'lulStudentLevel', 'lulPrimaryAffiliation', 'cn', 'mail', - 'givenName', 'sn', 'lulColleagueId', 'preferredLanguage' - ] - con.simple_bind_s(ARGS.ldap_user, ARGS.ldap_password) - - if (ARGS.query_date): - ldap_filter = '(&%s(lulPrimaryAffiliation=*)(createTimestamp>=%s))' % ( - '(objectclass=lulEduPerson)', ARGS.query_date - ) - elif (ARGS.query_cn): - ldap_filter = '(&%s(cn=%s))' % ( - '(objectclass=lulEduPerson)', ARGS.query_cn - ) - elif (ARGS.query_sn): - ldap_filter = '(&%s(sn=%s))' % ( - '(objectclass=lulEduPerson)', ARGS.query_sn - ) - elif (ARGS.query_id): - ldap_filter = '(&%s(lulColleagueId=%s))' % ( - '(objectclass=lulEduPerson)', ARGS.query_id - ) - - find_ldap_users(con, ldap_filter, attributes, auth) - - except ldap.LDAPError, exc: - print >> sys.stderr, "Could not connect: " + exc.message['info'] - if type(exc.message) == dict and exc.message.has_key('desc'): - print >> sys.stderr, exc.message['desc'] - else: - print >> sys.stderr, exc - sys.exit() - finally: - con.unbind() + attributes = [ + 'lulLibraryBarcode', + 'lulStudentLevel', 'lulPrimaryAffiliation', 'cn', 'mail', + 'givenName', 'sn', 'lulColleagueId', 'preferredLanguage' + ] + + if (ARGS.query_date): + ldap_filter = '(&%s(lulPrimaryAffiliation=*)(createTimestamp>=%s))' % ( + '(objectclass=lulEduPerson)', ARGS.query_date + ) + elif (ARGS.query_cn): + ldap_filter = '(&%s(cn=%s))' % ( + '', ARGS.query_cn + ) + elif (ARGS.query_sn): + ldap_filter = '(&%s(sn=%s))' % ( + '(objectclass=lulEduPerson)', ARGS.query_sn + ) + elif (ARGS.query_id): + ldap_filter = '(&%s(lulColleagueId=%s))' % ( + '(objectclass=lulEduPerson)', ARGS.query_id + ) + + find_ldap_users(con, ldap_filter, attributes, auth) def parse_args(): """ @@ -565,10 +589,13 @@ def parse_args(): args = parser.parse_args() return args -if __name__ == '__main__': - import doctest - doctest.testmod() +def main(): + """ + Set up connections and run code + """ + global ARGS + global AUTHTOKEN ARGS = parse_args() # Set the host for our requests @@ -578,9 +605,23 @@ if __name__ == '__main__': load_idl() # Log in and get an authtoken - AUTHTOKEN = osrf_login( - ARGS.eg_user, ARGS.eg_password, ARGS.eg_workstation - ) + AUTHTOKEN = osrf_login(ARGS.eg_user, ARGS.eg_password, ARGS.eg_workstation) + + try: + con = ldap.initialize(ARGS.ldap_server) + con.set_option(ldap.OPT_REFERRALS, 0) + con.simple_bind_s(ARGS.ldap_user, ARGS.ldap_password) + ldap_query(con, AUTHTOKEN) + + except ldap.LDAPError, exc: + print >> sys.stderr, "Could not connect: " + exc.message['info'] + if type(exc.message) == dict and exc.message.has_key('desc'): + print >> sys.stderr, exc.message['desc'] + else: + print >> sys.stderr, exc + sys.exit() + finally: + con.unbind() # UDATA = { # 'mail': ['dan@example.com'], @@ -591,6 +632,13 @@ if __name__ == '__main__': # } # create_evergreen_user(AUTHTOKEN, UDATA) - ldap_create_by_date(AUTHTOKEN) +if __name__ == '__main__': + import doctest + doctest.testmod() + + ARGS = None + AUTHTOKEN = None + + main() # vim: et:ts=4:sw=4:tw=78: -- 2.11.0