Experimental web.py frontend for creating Conifer accounts
authorDan Scott <dscott@laurentian.ca>
Tue, 10 Jul 2012 20:25:42 +0000 (16:25 -0400)
committerDan Scott <dscott@laurentian.ca>
Tue, 7 May 2013 18:57:47 +0000 (14:57 -0400)
Use web.py to surface a simple Web UI for generating Conifer accounts
based on the Laurentian ID of a given user. Required a little
refactoring of ldap_osrf_sync to make it usable as a module rather than
just as a script, but that's all for the better.

Signed-off-by: Dan Scott <dscott@laurentian.ca>
tools/patron-load/ldap_osrf_sync
tools/patron-load/ldap_osrf_sync.py [new symlink]
tools/patron-load/templates/index.html [new file with mode: 0644]
tools/patron-load/webui.py [new file with mode: 0644]

index c6c081e..658f20e 100755 (executable)
@@ -314,6 +314,8 @@ def find_ldap_users(con, ldap_filter, attributes, auth):
     """
     base_dn = 'o=lul'
     search_scope = ldap.SCOPE_SUBTREE
+    results = []
+    attributes = None
 
     try:
         result_id = con.search(base_dn, search_scope, ldap_filter, attributes)
@@ -329,6 +331,7 @@ def find_ldap_users(con, ldap_filter, attributes, auth):
                 res = create_evergreen_user(auth, user)
                 if res:
                     update_ldap_barcode(con, user)
+                    results.append(res)
             if ARGS.push_barcode:
                 if user.barcode:
                     continue
@@ -348,6 +351,8 @@ def find_ldap_users(con, ldap_filter, attributes, auth):
     except ldap.LDAPError, exc:
         print >> sys.stderr, exc
 
+    return results
+
 def get_barcode(auth, uid):
     """
     Retrieve the barcode for a user from Evergreen based on their user ID
@@ -511,7 +516,7 @@ def create_evergreen_user(auth, user):
     create_stat_cats(egau, user)
 
     print("Created: %s with barcode %s" % (egau.usrname(), user.barcode))
-    return user.barcode
+    return egau.usrname(), user.barcode
 
 def update_ldap_barcode(con, user):
     """
@@ -555,6 +560,9 @@ def ldap_query(con, auth):
     """
     Process LDAP users created since a given date
     """
+
+    ldap_filter = None
+
     attributes = [
         'lulLibraryBarcode', 'createTimestamp', 'lulAffiliation',
         'lulStudentLevel', 'lulPrimaryAffiliation', 'cn', 'mail',
@@ -580,7 +588,7 @@ def ldap_query(con, auth):
         )
     if not ldap_filter:
         return 
-    find_ldap_users(con, ldap_filter, attributes, auth)
+    return find_ldap_users(con, ldap_filter, attributes, auth)
 
 def parse_args():
     """
@@ -636,15 +644,20 @@ def parse_args():
     args = parser.parse_args()
     return args
 
-def main():
+def main(args=None):
     """
     Set up connections and run code
     """
 
+    results = []
     global ARGS
     global AUTHTOKEN
     ARGS = parse_args()
 
+    # override parsed args with anything that was passed in
+    if args:
+        ARGS = args
+
     # Set the host for our requests
     osrf.gateway.GatewayRequest.setDefaultHost(ARGS.eg_host)
 
@@ -671,7 +684,7 @@ def main():
         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)
+        results = ldap_query(con, AUTHTOKEN)
 
     except ldap.LDAPError, exc:
         print >> sys.stderr, "Could not connect: " + exc.message['info']
@@ -683,6 +696,8 @@ def main():
     finally:
         con.unbind()
 
+    return results
+
 #    UDATA = {
 #        'mail': ['dan@example.com'],
 #        'givenName':  ['Dan'],
diff --git a/tools/patron-load/ldap_osrf_sync.py b/tools/patron-load/ldap_osrf_sync.py
new file mode 120000 (symlink)
index 0000000..1263efc
--- /dev/null
@@ -0,0 +1 @@
+ldap_osrf_sync
\ No newline at end of file
diff --git a/tools/patron-load/templates/index.html b/tools/patron-load/templates/index.html
new file mode 100644 (file)
index 0000000..3087d83
--- /dev/null
@@ -0,0 +1,38 @@
+$def with (uid, users)
+<html>
+<head>
+<title>Laurentian LDAP->Conifer account creation</title>
+<style>
+:invalid { 
+  border-color: #e88;
+  -webkit-box-shadow: 0 0 5px rgba(255, 0, 0, .8);
+  -moz-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
+  -o-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
+  -ms-box-shadow: 0 0 5px rbba(255, 0, 0, .8);
+  box-shadow:0 0 5px rgba(255, 0, 0, .8);
+}
+</style>
+</head>
+<body>
+<h1>Laurentian LDAP->Conifer account creation</h1>
+$if uid:
+    $if len(users):
+        $for user, barcode in users:
+            <p>Created <strong>$user</strong> with barcode
+            <strong>$barcode</strong> for user ID <tt>$uid</tt></p>
+    $else:
+        <p>Tried to create user with ID # $uid, but we either could not find a
+        match, or it may already exist in Conifer.</p>
+
+<h2>Create an account</h2>
+<form action="/">
+    <label>Laurentian ID: <input type="number" name="uid"></label>
+    <input type="submit">
+</form>
+<h3>About this form</h3>
+<p>This form takes a Laurentian student or employee ID (normally 7 digits) as
+input, checks the LDAP directory for a match, and then attempts to create an
+account in Conifer with a new barcode that will then be pushed back into the
+LDAP directory.</p>
+</body>
+</html>
diff --git a/tools/patron-load/webui.py b/tools/patron-load/webui.py
new file mode 100644 (file)
index 0000000..c3af4fc
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+"A simple Web UI based on the web.py framework"
+
+import web
+import ldap_osrf_sync
+
+render = web.template.render('templates/')
+
+urls = (
+    '/(.*)', 'Index'
+)
+
+class Index:
+    "Adds a user based on their user ID"
+
+    def __init__(self):
+        self.args = LDAP_ARGS()
+
+    def GET(self, uid):
+        "Handle GET requests"
+
+        users = []
+
+        i = web.input(uid=None)
+
+        if i.uid:
+            uid = i.uid
+
+        if uid:
+            self.args.uid(uid)
+            users = ldap_osrf_sync.main(self.args)
+
+        return render.index(uid, users)
+
+class LDAP_ARGS:
+    def __init__(self):
+        self.ldap_server = ldap_osrf_sync.credentials.LDAP_HOST
+        self.ldap_user = ldap_osrf_sync.credentials.LDAP_DN
+        self.ldap_password = ldap_osrf_sync.credentials.LDAP_PW
+        self.eg_host = ldap_osrf_sync.credentials.OSRF_HOST
+        self.eg_user = ldap_osrf_sync.credentials.OSRF_USER
+        self.eg_password = ldap_osrf_sync.credentials.OSRF_PW
+        self.eg_workstation = ldap_osrf_sync.credentials.OSRF_WORK_OU
+        self.find_eg_user = None
+        self.dump_ldap = None
+        self.create_users = None
+        self.push_barcode = None
+        self.query_id = None
+        self.query_cn = None
+        self.query_sn = None
+        self.query_date = None
+
+    def uid(self, uid):
+        self.query_id = uid
+
+if __name__ == "__main__": 
+    app = web.application(urls, globals())
+    app.run()