/* Adds the authentication token to the user cache. The timeout for the auth token is based on the type of login as well as (if type=='opac') the org location id. Returns the event that should be returned to the user. Event must be freed */ static oilsEvent* oilsAuthHandleLoginOK( jsonObject* userObj, const char* uname, const char* type, int orgloc, const char* workstation ) { oilsEvent* response; long timeout; char* wsorg = jsonObjectToSimpleString(oilsFMGetObject(userObj, "ws_ou")); if(wsorg) { /* if there is a workstation, use it for the timeout */ osrfLogDebug( OSRF_LOG_MARK, "Auth session trying workstation id %d for auth timeout", atoi(wsorg)); timeout = oilsAuthGetTimeout( userObj, type, atoi(wsorg) ); free(wsorg); } else { osrfLogDebug( OSRF_LOG_MARK, "Auth session trying org from param [%d] for auth timeout", orgloc ); timeout = oilsAuthGetTimeout( userObj, type, orgloc ); } osrfLogDebug(OSRF_LOG_MARK, "Auth session timeout for %s: %ld", uname, timeout ); char* string = va_list_to_string( "%d.%ld.%s", (long) getpid(), time(NULL), uname ); char* authToken = md5sum(string); char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); const char* ws = (workstation) ? workstation : ""; osrfLogActivity(OSRF_LOG_MARK, "successful login: username=%s, authtoken=%s, workstation=%s", uname, authToken, ws ); oilsFMSetString( userObj, "passwd", "" ); jsonObject* cacheObj = jsonParseFmt( "{\"authtime\": %ld}", timeout ); jsonObjectSetKey( cacheObj, "userobj", jsonObjectClone(userObj)); if( !strcmp( type, OILS_AUTH_PERSIST )) { // Add entries for endtime and reset_interval, so that we can gracefully // extend the session a bit if the user is active toward the end of the // timeout originally specified. time_t endtime = time( NULL ) + timeout; jsonObjectSetKey( cacheObj, "endtime", jsonNewNumberObject( (double) endtime ) ); // Reset interval is hard-coded for now, but if we ever want to make it // configurable, this is the place to do it: jsonObjectSetKey( cacheObj, "reset_interval", jsonNewNumberObject( (double) DEFAULT_RESET_INTERVAL )); } osrfCachePutObject( authKey, cacheObj, (time_t) timeout ); jsonObjectFree(cacheObj); osrfLogInternal(OSRF_LOG_MARK, "oilsAuthHandleLoginOK(): Placed user object into cache"); jsonObject* payload = jsonParseFmt( "{ \"authtoken\": \"%s\", \"authtime\": %ld }", authToken, timeout ); response = oilsNewEvent2( OSRF_LOG_MARK, OILS_EVENT_SUCCESS, payload ); free(string); free(authToken); free(authKey); jsonObjectFree(payload); return response; }
oilsEvent* oilsUtilsCheckPerms( int userid, int orgid, char* permissions[], int size ) { if (!permissions) return NULL; int i; oilsEvent* evt = NULL; // Find the root org unit, i.e. the one with no parent. // Assumption: there is only one org unit with no parent. if (orgid == -1) { jsonObject* where_clause = jsonParse( "{\"parent_ou\":null}" ); jsonObject* org = oilsUtilsQuickReq( "open-ils.cstore", "open-ils.cstore.direct.actor.org_unit.search", where_clause ); jsonObjectFree( where_clause ); orgid = (int)jsonObjectGetNumber( oilsFMGetObject( org, "id" ) ); jsonObjectFree(org); } for( i = 0; i < size && permissions[i]; i++ ) { char* perm = permissions[i]; jsonObject* params = jsonParseFmt("[%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( OSRF_LOG_MARK, OILS_EVENT_PERM_FAILURE, perm, orgid ); jsonObjectFree(params); jsonObjectFree(o); free(r); if(evt) break; } return evt; }
int oilsUtilsGetRootOrgId() { // return the cached value if we have it. if (rootOrgId > 0) return rootOrgId; jsonObject* where_clause = jsonParse("{\"parent_ou\":null}"); jsonObject* org = oilsUtilsQuickReq( "open-ils.cstore", "open-ils.cstore.direct.actor.org_unit.search", where_clause ); rootOrgId = (int) jsonObjectGetNumber(oilsFMGetObject(org, "id")); jsonObjectFree(where_clause); jsonObjectFree(org); return rootOrgId; }
/** @brief Determine the login timeout. @param userObj Pointer to an object describing the user. @param type Pointer to one of four possible character strings identifying the login type. @param orgloc Org unit to use for settings lookups (negative or zero means unspecified) @return The length of the timeout, in seconds. The default timeout value comes from the configuration file, and depends on the login type. The default may be overridden by a corresponding org unit setting. The @a orgloc parameter says what org unit to use for the lookup. If @a orgloc <= 0, or if the lookup for @a orgloc yields no result, we look up the setting for the user's home org unit instead (except that if it's the same as @a orgloc we don't bother repeating the lookup). Whether defined in the config file or in an org unit setting, a timeout value may be expressed as a raw number (i.e. all digits, possibly with leading and/or trailing white space) or as an interval string to be translated into seconds by PostgreSQL. */ static long oilsAuthGetTimeout( const jsonObject* userObj, const char* type, int orgloc ) { if(!_oilsAuthOPACTimeout) { /* Load the default timeouts */ jsonObject* value_obj; value_obj = osrf_settings_host_value_object( "/apps/open-ils.auth/app_settings/default_timeout/opac" ); _oilsAuthOPACTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj )); jsonObjectFree(value_obj); if( -1 == _oilsAuthOPACTimeout ) { osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for OPAC logins" ); _oilsAuthOPACTimeout = 0; } value_obj = osrf_settings_host_value_object( "/apps/open-ils.auth/app_settings/default_timeout/staff" ); _oilsAuthStaffTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj )); jsonObjectFree(value_obj); if( -1 == _oilsAuthStaffTimeout ) { osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for staff logins" ); _oilsAuthStaffTimeout = 0; } value_obj = osrf_settings_host_value_object( "/apps/open-ils.auth/app_settings/default_timeout/temp" ); _oilsAuthOverrideTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj )); jsonObjectFree(value_obj); if( -1 == _oilsAuthOverrideTimeout ) { osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for temp logins" ); _oilsAuthOverrideTimeout = 0; } value_obj = osrf_settings_host_value_object( "/apps/open-ils.auth/app_settings/default_timeout/persist" ); _oilsAuthPersistTimeout = oilsUtilsIntervalToSeconds( jsonObjectGetString( value_obj )); jsonObjectFree(value_obj); if( -1 == _oilsAuthPersistTimeout ) { osrfLogWarning( OSRF_LOG_MARK, "Invalid default timeout for persist logins" ); _oilsAuthPersistTimeout = 0; } osrfLogInfo(OSRF_LOG_MARK, "Set default auth timeouts: " "opac => %ld : staff => %ld : temp => %ld : persist => %ld", _oilsAuthOPACTimeout, _oilsAuthStaffTimeout, _oilsAuthOverrideTimeout, _oilsAuthPersistTimeout ); } int home_ou = (int) jsonObjectGetNumber( oilsFMGetObject( userObj, "home_ou" )); if(orgloc < 1) orgloc = home_ou; char* setting = NULL; long default_timeout = 0; if( !strcmp( type, OILS_AUTH_OPAC )) { setting = OILS_ORG_SETTING_OPAC_TIMEOUT; default_timeout = _oilsAuthOPACTimeout; } else if( !strcmp( type, OILS_AUTH_STAFF )) { setting = OILS_ORG_SETTING_STAFF_TIMEOUT; default_timeout = _oilsAuthStaffTimeout; } else if( !strcmp( type, OILS_AUTH_TEMP )) { setting = OILS_ORG_SETTING_TEMP_TIMEOUT; default_timeout = _oilsAuthOverrideTimeout; } else if( !strcmp( type, OILS_AUTH_PERSIST )) { setting = OILS_ORG_SETTING_PERSIST_TIMEOUT; default_timeout = _oilsAuthPersistTimeout; } // Get the org unit setting, if there is one. char* timeout = oilsUtilsFetchOrgSetting( orgloc, setting ); if(!timeout) { if( orgloc != home_ou ) { osrfLogDebug(OSRF_LOG_MARK, "Auth timeout not defined for org %d, " "trying home_ou %d", orgloc, home_ou ); timeout = oilsUtilsFetchOrgSetting( home_ou, setting ); } } if(!timeout) return default_timeout; // No override from org unit setting // Translate the org unit setting to a number long t; if( !*timeout ) { osrfLogWarning( OSRF_LOG_MARK, "Timeout org unit setting is an empty string for %s login; using default", timeout, type ); t = default_timeout; } else { // Treat timeout string as an interval, and convert it to seconds t = oilsUtilsIntervalToSeconds( timeout ); if( -1 == t ) { // Unable to convert; possibly an invalid interval string osrfLogError( OSRF_LOG_MARK, "Unable to convert timeout interval \"%s\" for %s login; using default", timeout, type ); t = default_timeout; } } free(timeout); return t; }
/** @brief Return a string with the value of a specified column in a row object. @param object Pointer to the row object. @param field Name of the column. @return Pointer to a newly allocated string representing the value of the specified column, or NULL in case of error. The row object must be a JSON_ARRAY with a classname. The column value must be a JSON_STRING or a JSON_NUMBER. Any other object type results in a return of NULL. The calling code is responsible for freeing the returned string by calling free(). */ char* oilsFMGetString( const jsonObject* object, const char* field ) { return jsonObjectToSimpleString(oilsFMGetObject( object, field )); }
/** @brief Return a const string with the value of a specified column in a row object. @param object Pointer to the row object. @param field Name of the column. @return Pointer to a const string representing the value of the specified column, or NULL in case of error. The row object must be a JSON_ARRAY with a classname. The column value must be a JSON_STRING or a JSON_NUMBER. Any other object type results in a return of NULL. The return value points into the internal contents of the row object, which retains ownership. */ const char* oilsFMGetStringConst( const jsonObject* object, const char* field ) { return jsonObjectGetString(oilsFMGetObject( object, field )); }