User activity tracking: open-ils.auth additions
authorBill Erickson <berick@esilibrary.com>
Mon, 16 Jan 2012 21:19:41 +0000 (16:19 -0500)
committerThomas Berezansky <tsbere@mvlc.org>
Thu, 8 Mar 2012 18:50:06 +0000 (13:50 -0500)
* Creates usr_activity entries for login and authentication verification
  requests

* Adds a new parameter to open-ils.auth.authenticate.[complete|verify]
  methods called "agent" which maps to the usr_activity column for "ewho"
  (the UI or 3rd-party that initiated the action).

* Adds a new API call "open-ils.auth.authenticate.verify", which behaves
  almost identically to authenticate.complete, with the exception that it
  does not "log in" (i.e. create an auth token and cache the user object).
  Instead, it simply returns a SUCCESS event if the username/barcode and
  password combination are valid.

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Thomas Berezansky <tsbere@mvlc.org>
Open-ILS/include/openils/oils_utils.h
Open-ILS/src/c-apps/oils_auth.c
Open-ILS/src/c-apps/oils_utils.c

index 4357a40..3554d21 100644 (file)
@@ -104,6 +104,12 @@ int oilsUtilsIsDBTrue( const char* val );
 
 long oilsUtilsIntervalToSeconds( const char* interval );
 
+/**
+ * Creates actor.usr_activity entries
+ * @return The number of rows created.  0 or 1.
+ */
+int oilsUtilsTrackUserActivity( long usr, const char* ewho, const char* ewhat, const char* ehow );
+
 #ifdef __cplusplus
 }
 #endif
index 7c545de..121e5dc 100644 (file)
@@ -64,6 +64,15 @@ int osrfAppInitialize() {
 
        osrfAppRegisterMethod(
                MODULENAME,
+               "open-ils.auth.authenticate.verify",
+               "oilsAuthComplete",
+               "Verifies the user provided a valid username and password."
+               "Params and are the same as open-ils.auth.authenticate.complete."
+               "Returns SUCCESS event on success, failure event on failure", 1, 0);
+
+
+       osrfAppRegisterMethod(
+               MODULENAME,
                "open-ils.auth.session.retrieve",
                "oilsAuthSessionRetrieve",
                "Pass in the auth token and this retrieves the user object.  The auth "
@@ -553,6 +562,7 @@ static oilsEvent* oilsAuthVerifyWorkstation(
                - "type"
                - "org"
                - "workstation"
+               - "agent" (what software/interface/3rd-party is making the request)
 
        The password is required.  Either a username or a barcode must also be present.
 
@@ -575,6 +585,7 @@ int oilsAuthComplete( osrfMethodContext* ctx ) {
        int orgloc        = (int) jsonObjectGetNumber(jsonObjectGetKeyConst(args, "org"));
        const char* workstation = jsonObjectGetString(jsonObjectGetKeyConst(args, "workstation"));
        const char* barcode     = jsonObjectGetString(jsonObjectGetKeyConst(args, "barcode"));
+       const char* ewho        = jsonObjectGetString(jsonObjectGetKeyConst(args, "agent"));
 
        const char* ws = (workstation) ? workstation : "";
 
@@ -709,8 +720,23 @@ int oilsAuthComplete( osrfMethodContext* ctx ) {
                uname = freeable_uname = oilsFMGetString( userObj, "usrname" );
        }
 
-       if( passOK ) {
-               response = oilsAuthHandleLoginOK( userObj, uname, type, orgloc, workstation );
+       if( passOK ) { // login successful  
+        
+               char* ewhat = "login";
+
+               if (0 == strcmp(ctx->method->name, "open-ils.auth.authenticate.verify")) {
+                       response = oilsNewEvent( OSRF_LOG_MARK, OILS_EVENT_SUCCESS );
+                       ewhat = "verify";
+
+               } else {
+                       response = oilsAuthHandleLoginOK( userObj, uname, type, orgloc, workstation );
+               }
+
+               oilsUtilsTrackUserActivity(
+                       oilsFMGetObjectId(userObj), 
+                       ewho, ewhat, 
+                       osrfAppSessionGetIngress()
+               );
 
        } else {
                response = oilsNewEvent( OSRF_LOG_MARK, OILS_EVENT_AUTH_FAILED );
index 2be8420..cb334ac 100644 (file)
@@ -120,6 +120,50 @@ long oilsFMGetObjectId( const jsonObject* obj ) {
        return id;
 }
 
+int oilsUtilsTrackUserActivity(long usr, const char* ewho, const char* ewhat, const char* ehow) {
+    if (!usr && !(ewho || ewhat || ehow)) return 0;
+    int rowcount = 0;
+
+    jsonObject* params = jsonParseFmt(
+        "{\"from\":[\"actor.insert_usr_activity\", %ld, \"%s\", \"%s\", \"%s\"]}",
+        usr, 
+        (NULL == ewho)  ? "" : ewho, 
+        (NULL == ewhat) ? "" : ewhat, 
+        (NULL == ehow)  ? "" : ehow
+    );
+
+       osrfAppSession* session = osrfAppSessionClientInit("open-ils.cstore");
+    osrfAppSessionConnect(session);
+    int reqid = osrfAppSessionSendRequest(session, NULL, "open-ils.cstore.transaction.begin", 1);
+       osrfMessage* omsg = osrfAppSessionRequestRecv(session, reqid, 60);
+
+    if(omsg) {
+        osrfMessageFree(omsg);
+        reqid = osrfAppSessionSendRequest(session, params, "open-ils.cstore.json_query", 1);
+           omsg = osrfAppSessionRequestRecv(session, reqid, 60);
+
+        if(omsg) {
+            const jsonObject* rows = osrfMessageGetResult(omsg);
+            if (rows) rowcount = rows->size;
+            osrfMessageFree(omsg); // frees rows
+            if (rowcount) {
+                reqid = osrfAppSessionSendRequest(session, NULL, "open-ils.cstore.transaction.commit", 1);
+                   omsg = osrfAppSessionRequestRecv(session, reqid, 60);
+                osrfMessageFree(omsg);
+            } else {
+                reqid = osrfAppSessionSendRequest(session, NULL, "open-ils.cstore.transaction.rollback", 1);
+                   omsg = osrfAppSessionRequestRecv(session, reqid, 60);
+                osrfMessageFree(omsg);
+            }
+        }
+    }
+
+    osrfAppSessionFree(session); // calls disconnect internally
+    jsonObjectFree(params);
+    return rowcount;
+}
+
+
 
 oilsEvent* oilsUtilsCheckPerms( int userid, int orgid, char* permissions[], int size ) {
        if (!permissions) return NULL;