LP#1485374: add way for C code to make TZ-aware subrequests
authorGalen Charlton <gmc@esilibrary.com>
Tue, 23 Feb 2016 17:09:15 +0000 (12:09 -0500)
committerGalen Charlton <gmc@esilibrary.com>
Tue, 23 Feb 2016 17:09:15 +0000 (12:09 -0500)
This patch adds a helper routine to allow C
methods to make subrequests that pass the client
time zone along. This helper is in turn used during
authentication to ensure that the user object
that is returned has timestamps that are in the
time zone of the client that makes the original
authentication request.

Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/include/openils/oils_utils.h
Open-ILS/src/c-apps/oils_auth.c
Open-ILS/src/c-apps/oils_utils.c

index 3554d21..7b64f6a 100644 (file)
@@ -13,6 +13,7 @@
 #include "oils_constants.h"
 #include "opensrf/osrf_app_session.h"
 #include "opensrf/osrf_settings.h"
+#include "opensrf/osrf_application.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -65,6 +66,9 @@ oilsEvent* oilsUtilsCheckPerms( int userid, int orgid, char* permissions[], int
 jsonObject* oilsUtilsQuickReq( const char* service, const char* method,
                const jsonObject* params );
 
+jsonObject* oilsUtilsQuickReqCtx( osrfMethodContext* ctx, const char* service,
+               const char* method, const jsonObject* params );
+
 jsonObject* oilsUtilsStorageReq( const char* method, const jsonObject* params );
 
 jsonObject* oilsUtilsCStoreReq( const char* method, const jsonObject* params );
@@ -73,7 +77,7 @@ jsonObject* oilsUtilsCStoreReq( const char* method, const jsonObject* params );
  * Searches the storage server for a user with the given username 
  * Caller is responsible for freeing the returned object
  */
-jsonObject* oilsUtilsFetchUserByUsername( const char* name );
+jsonObject* oilsUtilsFetchUserByUsername( osrfMethodContext* ctx, const char* name );
 
 
 /**
index bd79770..5504a7a 100644 (file)
@@ -621,7 +621,7 @@ int oilsAuthComplete( osrfMethodContext* ctx ) {
        // Fetch a row from the actor.usr table, by username if available,
        // or by barcode if not.
        if(uname) {
-               userObj = oilsUtilsFetchUserByUsername( uname );
+               userObj = oilsUtilsFetchUserByUsername( ctx, uname );
                if( userObj && JSON_NULL == userObj->type ) {
                        jsonObjectFree( userObj );
                        userObj = NULL;         // username not found
@@ -633,8 +633,8 @@ int oilsAuthComplete( osrfMethodContext* ctx ) {
                osrfLogInfo( OSRF_LOG_MARK, "Fetching user by barcode %s", barcode );
 
                jsonObject* params = jsonParseFmt("{\"barcode\":\"%s\"}", barcode);
-               jsonObject* card = oilsUtilsQuickReq(
-                       "open-ils.cstore", "open-ils.cstore.direct.actor.card.search", params );
+               jsonObject* card = oilsUtilsQuickReqCtx(
+                       ctx, "open-ils.cstore", "open-ils.cstore.direct.actor.card.search", params );
                jsonObjectFree( params );
 
                if( card && card->type != JSON_NULL ) {
@@ -648,8 +648,8 @@ int oilsAuthComplete( osrfMethodContext* ctx ) {
                        jsonObjectFree( card );
                        params = jsonParseFmt( "[%s]", userid );
                        free( userid );
-                       userObj = oilsUtilsQuickReq(
-                                       "open-ils.cstore", "open-ils.cstore.direct.actor.user.retrieve", params );
+                       userObj = oilsUtilsQuickReqCtx(
+                                       ctx, "open-ils.cstore", "open-ils.cstore.direct.actor.user.retrieve", params );
                        jsonObjectFree( params );
                        if( userObj && JSON_NULL == userObj->type ) {
                                // user not found (shouldn't happen, due to foreign key)
index cb334ac..2dd87f8 100644 (file)
@@ -244,6 +244,42 @@ jsonObject* oilsUtilsQuickReq( const char* service, const char* method,
 }
 
 /**
+       @brief Perform a remote procedure call, propagating session
+        locale and timezone
+       @param service The name of the service to invoke.
+       @param method The name of the method to call.
+       @param params The parameters to be passed to the method, if any.
+       @return A copy of whatever the method returns as a result, or a JSON_NULL if the method
+       doesn't return anything.
+
+       If the @a params parameter points to a JSON_ARRAY, pass each element of the array
+       as a separate parameter.  If it points to any other kind of jsonObject, pass it as a
+       single parameter.  If it is NULL, pass no parameters.
+
+       The calling code is responsible for freeing the returned object by calling jsonObjectFree().
+*/
+jsonObject* oilsUtilsQuickReqCtx( osrfMethodContext* ctx, const char* service,
+                const char* method, const jsonObject* params ) {
+       if(!(service && method && ctx)) return NULL;
+
+       osrfLogDebug(OSRF_LOG_MARK, "oilsUtilsQuickReqCtx(): %s - %s (%s)", service, method, ctx->session->session_tz );
+
+       // Open an application session with the service, and send the request
+       osrfAppSession* session = osrfAppSessionClientInit( service );
+       osrf_app_session_set_tz(session, ctx->session->session_tz);
+       int reqid = osrfAppSessionSendRequest( session, params, method, 1 );
+
+       // Get the response
+       osrfMessage* omsg = osrfAppSessionRequestRecv( session, reqid, 60 );
+       jsonObject* result = jsonObjectClone( osrfMessageGetResult(omsg) );
+
+       // Clean up
+       osrfMessageFree(omsg);
+       osrfAppSessionFree(session);
+       return result;
+}
+
+/**
        @brief Call a method of the open-ils.storage service.
        @param method Name of the method.
        @param params Parameters to be passed to the method, if any.
@@ -287,11 +323,11 @@ jsonObject* oilsUtilsCStoreReq( const char* method, const jsonObject* params ) {
 
        The calling code is responsible for freeing the returned object by calling jsonObjectFree().
 */
-jsonObject* oilsUtilsFetchUserByUsername( const char* name ) {
+jsonObject* oilsUtilsFetchUserByUsername( osrfMethodContext* ctx, const char* name ) {
        if(!name) return NULL;
        jsonObject* params = jsonParseFmt("{\"usrname\":\"%s\"}", name);
-       jsonObject* user = oilsUtilsQuickReq(
-               "open-ils.cstore", "open-ils.cstore.direct.actor.user.search", params );
+       jsonObject* user = oilsUtilsQuickReqCtx(
+               ctx, "open-ils.cstore", "open-ils.cstore.direct.actor.user.search", params );
 
        jsonObjectFree(params);
        long id = oilsFMGetObjectId(user);