From b7d2b2c6472fdfefdc0abe7aaaff668975614c59 Mon Sep 17 00:00:00 2001 From: erickson Date: Tue, 6 Dec 2005 23:44:08 +0000 Subject: [PATCH] added some utility functions like permissions checking, one-off requests, etc. auth code now checks permissions for OPAC_LOGIN and STAFF_LOGIN before allowing the login git-svn-id: svn://svn.open-ils.org/ILS/trunk@2245 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/c-apps/oils_auth.c | 62 ++++++++++++--------------- Open-ILS/src/c-apps/oils_constants.h | 2 + Open-ILS/src/c-apps/oils_event.h | 3 ++ Open-ILS/src/c-apps/oils_utils.c | 63 ++++++++++++++++++++++++++++ Open-ILS/src/c-apps/oils_utils.h | 32 ++++++++++++++ 5 files changed, 126 insertions(+), 36 deletions(-) diff --git a/Open-ILS/src/c-apps/oils_auth.c b/Open-ILS/src/c-apps/oils_auth.c index 1ca1476b96..83e9728772 100644 --- a/Open-ILS/src/c-apps/oils_auth.c +++ b/Open-ILS/src/c-apps/oils_auth.c @@ -29,7 +29,7 @@ int osrfAppInitialize() { "open-ils.auth.authenticate.complete", "oilsAuthComplete", "Completes the authentication process and returns the auth token " - "PARAMS(username, md5sum( seed + password ) )", 2, 0 ); + "PARAMS(username, md5sum( seed + password ), type )", 2, 0 ); osrfAppRegisterMethod( MODULENAME, @@ -90,55 +90,46 @@ int oilsAuthComplete( osrfMethodContext* ctx ) { char* uname = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0)); char* password = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 1)); - char* storageMethod = "open-ils.storage.direct.actor.user.search.usrname.atomic"; - osrfMessage* omsg = NULL; + char* type = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 2)); + if(!type) type = "staff"; if( uname && password ) { oilsEvent* response = NULL; - - /* grab the user object from storage */ - osrfLogDebug( "oilsAuth calling method %s with username %s", storageMethod, uname ); - - osrfAppSession* session = osrfAppSessionClientInit( "open-ils.storage" ); /**/ - jsonObject* params = jsonParseString("[\"%s\"]", uname); - int reqid = osrfAppSessionMakeRequest( session, params, storageMethod, 1, NULL ); - jsonObjectFree(params); - osrfLogInternal("oilsAuth waiting from response from storage..."); - omsg = osrfAppSessionRequestRecv( session, reqid, 60 ); /**/ - osrfLogInternal("oilsAuth storage request returned"); - - if(!omsg) { - osrfAppSessionFree(session); - return osrfAppRequestRespondException( ctx->session, ctx->request, - "No response from storage server for method %s", storageMethod ); - } - - jsonObject* userObj = osrfMessageGetResult(omsg); - - char* _j = jsonObjectToJSON(userObj); - osrfLogDebug( "Auth received user object from storage: %s", _j ); - free(_j); - - /* the method is atomic, grab the first user we receive */ - if( userObj ) userObj = jsonObjectGetIndex(userObj, 0); + jsonObject* userObj = oilsUtilsFetchUserByUsername( uname ); /* XXX */ - if(!userObj) { /* XXX needs to be a 'friendly' exception */ - osrfMessageFree(omsg); - osrfAppSessionFree(session); + if(!userObj) { response = oilsNewEvent( OILS_EVENT_AUTH_FAILED ); osrfAppRespondComplete( ctx, oilsEventToJSON(response) ); oilsEventFree(response); return 0; + } + + /* check to see if the user is allowed to login */ + oilsEvent* perm = NULL; + if(!strcmp(type, "opac")) { + char* permissions[] = { "OPAC_LOGIN" }; + perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 ); + + } else if(!strcmp(type, "staff")) { + char* permissions[] = { "STAFF_LOGIN" }; + perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 ); + } + + if(perm) { + jsonObjectFree(userObj); + osrfAppRespondComplete( ctx, oilsEventToJSON(perm) ); + oilsEventFree(perm); + return 0; } + + char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/ char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/ if(!seed) { - osrfMessageFree(omsg); - osrfAppSessionFree(session); return osrfAppRequestRespondException( ctx->session, ctx->request, "No authentication seed found. " "open-ils.auth.authenticate.init must be called first"); @@ -165,6 +156,7 @@ int oilsAuthComplete( osrfMethodContext* ctx ) { osrfLogInternal("oilsAuthComplete(): Placed user object into cache"); response = oilsNewEvent2( OILS_EVENT_SUCCESS, jsonNewObject(authToken) ); free(string); free(authToken); free(authKey); + jsonObjectFree(userObj); } else { @@ -175,8 +167,6 @@ int oilsAuthComplete( osrfMethodContext* ctx ) { osrfLogInternal("oilsAuthComplete responding to client"); osrfAppRespondComplete( ctx, oilsEventToJSON(response) ); oilsEventFree(response); - osrfMessageFree(omsg); - osrfAppSessionFree(session); } else { return osrfAppRequestRespondException( ctx->session, ctx->request, diff --git a/Open-ILS/src/c-apps/oils_constants.h b/Open-ILS/src/c-apps/oils_constants.h index a754bf5980..dc79b65f64 100644 --- a/Open-ILS/src/c-apps/oils_constants.h +++ b/Open-ILS/src/c-apps/oils_constants.h @@ -1,3 +1,5 @@ #define OILS_EVENT_SUCCESS "SUCCESS" #define OILS_EVENT_AUTH_FAILED "LOGIN_FAILED" +#define OILS_EVENT_PERM_FAILURE "PERM_FAILURE" + diff --git a/Open-ILS/src/c-apps/oils_event.h b/Open-ILS/src/c-apps/oils_event.h index 767207edb9..226e7a79b0 100644 --- a/Open-ILS/src/c-apps/oils_event.h +++ b/Open-ILS/src/c-apps/oils_event.h @@ -1,3 +1,5 @@ +#ifndef OILS_EVENT_HEADER +#define OILS_EVENT_HEADER #include "objson/object.h" #include "opensrf/utils.h" #include "opensrf/log.h" @@ -48,3 +50,4 @@ void oilsEventFree( oilsEvent* event ); +#endif diff --git a/Open-ILS/src/c-apps/oils_utils.c b/Open-ILS/src/c-apps/oils_utils.c index 19e1bcff30..0afb7c5259 100644 --- a/Open-ILS/src/c-apps/oils_utils.c +++ b/Open-ILS/src/c-apps/oils_utils.c @@ -26,3 +26,66 @@ int oilsFMSetString( jsonObject* object, char* field, char* string ) { } return -1; } + + +long oilsFMGetObjectId( jsonObject* obj ) { + long id = -1; + if(!obj) return id; + char* ids = oilsFMGetString( obj, "id" ); + if(ids) { id = atol(ids); free(ids); } + return id; +} + + +oilsEvent* oilsUtilsCheckPerms( int userid, int orgid, char* permissions[], int size ) { + if(!permissions) return NULL; + int i; + oilsEvent* evt = NULL; + if(orgid == -1) orgid = 1; /* XXX */ + + for( i = 0; i != size && permissions[i]; i++ ) { + + char* perm = permissions[i]; + jsonObject* params = jsonParseString("[%d, \"%s\", %d]", userid, perm, orgid); + jsonObject* o = oilsUtilsQuickReq( "open-ils.storage", + "open-ils.storage.permission.user_has_perm", params ); + + char* r = jsonObjectToSimpleString(o); + + if(r && !strcmp(r, "0")) + evt = oilsNewEvent3( OILS_EVENT_PERM_FAILURE, perm, orgid ); + + jsonObjectFree(params); + jsonObjectFree(o); + free(r); + + if(evt) break; + } + + return evt; +} + +jsonObject* oilsUtilsQuickReq( char* service, char* method, jsonObject* params ) { + if(!(service && method)) return NULL; + osrfLogDebug("oilsUtilsQuickReq(): %s - %s", service, method ); + osrfAppSession* session = osrfAppSessionClientInit( service ); + int reqid = osrfAppSessionMakeRequest( session, params, method, 1, NULL ); + osrfMessage* omsg = osrfAppSessionRequestRecv( session, reqid, 60 ); + jsonObject* result = jsonObjectClone(osrfMessageGetResult(omsg)); + osrfMessageFree(omsg); + osrfAppSessionFree(session); + return result; +} + + + +jsonObject* oilsUtilsFetchUserByUsername( char* name ) { + if(!name) return NULL; + jsonObject* params = jsonParseString("[\"%s\"]", name); + jsonObject* r = oilsUtilsQuickReq( "open-ils.storage", + "open-ils.storage.direct.actor.user.search.usrname.atomic", params ); + jsonObject* user = jsonObjectClone(jsonObjectGetIndex( r, 0 )); + jsonObjectFree(r); + return user; +} + diff --git a/Open-ILS/src/c-apps/oils_utils.h b/Open-ILS/src/c-apps/oils_utils.h index a9c502b685..02d12fa2b6 100644 --- a/Open-ILS/src/c-apps/oils_utils.h +++ b/Open-ILS/src/c-apps/oils_utils.h @@ -1,6 +1,9 @@ #include "objson/object.h" #include "opensrf/log.h" #include "openils/fieldmapper_lookup.h" +#include "oils_event.h" +#include "oils_constants.h" +#include "opensrf/osrf_app_session.h" /** Returns the string value for field 'field' in the given object. @@ -32,3 +35,32 @@ jsonObject* oilsFMGetObject( jsonObject* object, char* field ); @return 0 if the field was updated successfully, -1 on error */ int oilsFMSetString( jsonObject* object, char* field, char* string ); + +/** + * Returns the data stored in the id field of the object if it exists + * returns -1 if the id field or the id value is not found + */ +long oilsFMGetObjectId( jsonObject* obj ); + + +/** + * Checks if the user has each permission at the given org unit + * Passing in a -1 for the orgid means to use the top level org unit + * The first permission that fails causes the corresponding permission + * failure event to be returned + * returns NULL if all permissions succeed + */ +oilsEvent* oilsUtilsCheckPerms( int userid, int orgid, char* permissions[], int size ); + + +/** + * Performs a single request and returns the resulting data + * Caller is responsible for freeing the returned response object + */ +jsonObject* oilsUtilsQuickReq( char* service, char* method, jsonObject* params ); + +/** + * Searches the storage server for a user with the given username + * Caller is responsible for freeing the returned object + */ +jsonObject* oilsUtilsFetchUserByUsername( char* name ); -- 2.43.2