static void clear_query_stack( void );
static const jsonObject* verifyUserPCRUD( osrfMethodContext* );
-static int verifyObjectPCRUD( osrfMethodContext*, const jsonObject*, const int );
+static int verifyObjectPCRUD( osrfMethodContext*, osrfHash*, const jsonObject*, const int );
static const char* org_tree_root( osrfMethodContext* ctx );
static jsonObject* single_hash( const char* key, const char* value );
return -1;
}
- // Return each row to the client (except that some may be suppressed by PCRUD)
+ // Return each row to the client
jsonObject* cur = 0;
unsigned long res_idx = 0;
while((cur = jsonObjectGetIndex( obj, res_idx++ ) )) {
- if( enforce_pcrud && !verifyObjectPCRUD( ctx, cur, obj->size ))
- continue;
+ // We used to discard based on perms here, but now that's
+ // inside doFieldmapperSearch()
osrfAppRespond( ctx, cur );
}
jsonObjectFree( obj );
jsonObject* cur;
unsigned long res_idx = 0;
while((cur = jsonObjectGetIndex( obj, res_idx++ ) )) {
- if( enforce_pcrud && !verifyObjectPCRUD( ctx, cur, obj->size ))
- continue; // Suppress due to lack of permission
- else
- osrfAppRespond( ctx,
- oilsFMGetObject( cur, osrfHashGet( class_meta, "primarykey" ) ) );
+ // We used to discard based on perms here, but now that's
+ // inside doFieldmapperSearch()
+ osrfAppRespond( ctx,
+ oilsFMGetObject( cur, osrfHashGet( class_meta, "primarykey" ) ) );
}
jsonObjectFree( obj );
}
if( enforce_pcrud )
- return verifyObjectPCRUD( ctx, param, 1 );
+ return verifyObjectPCRUD( ctx, class, param, 1 );
else
return 1;
}
/**
@brief For PCRUD: Determine whether the current user may access the current row.
@param ctx Pointer to the method context.
+ @param class Same as ctx->method->userData's item for key "class" except when called in recursive doFieldmapperSearch
@param obj Pointer to the row being potentially accessed.
@return 1 if access is permitted, or 0 if it isn't.
The @a obj parameter points to a JSON_HASH of column values, keyed on column name.
*/
-static int verifyObjectPCRUD ( osrfMethodContext* ctx, const jsonObject* obj, const int rs_size ) {
+static int verifyObjectPCRUD ( osrfMethodContext* ctx, osrfHash *class, const jsonObject* obj, const int rs_size ) {
dbhandle = writehandle;
// Figure out what class and method are involved
osrfHash* method_metadata = (osrfHash*) ctx->method->userData;
- osrfHash* class = osrfHashGet( method_metadata, "class" );
const char* method_type = osrfHashGet( method_metadata, "methodtype" );
// Set fetch to 1 in all cases except for inserts, meaning that for local or foreign
// Get a list of permissions from the permacrud entry.
osrfStringArray* permission = osrfHashGet( pcrud, "permission" );
if( permission->size == 0 ) {
- osrfLogDebug( OSRF_LOG_MARK, "No permissions required for this action, passing through" );
+ osrfLogDebug(
+ OSRF_LOG_MARK,
+ "No permissions required for this action (class %s), passing through",
+ osrfHashGet(class, "classname")
+ );
return 1;
}
if( fetch ) {
// Fetch the row so that we can look at the foreign key(s)
+ osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
jsonObject* _tmp_params = single_hash( pkey, pkey_value );
jsonObject* _list = doFieldmapperSearch( ctx, class, _tmp_params, NULL, &err );
jsonObjectFree( _tmp_params );
+ osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
param = jsonObjectExtractIndex( _list, 0 );
jsonObjectFree( _list );
// Look up the row to which the foreign key points
jsonObject* _tmp_params = single_hash( foreign_pkey, foreign_pkey_value );
+
+ osrfHashSet((osrfHash*) ctx->method->userData, "1", "inside_verify");
jsonObject* _list = doFieldmapperSearch(
ctx, osrfHashGet( oilsIDL(), class_name ), _tmp_params, NULL, &err );
+ osrfHashSet((osrfHash*) ctx->method->userData, "0", "inside_verify");
jsonObject* _fparam = NULL;
if( _list && JSON_ARRAY == _list->type && _list->size > 0 )
if( enforce_pcrud ) {
// no result, skip this entirely
- if(NULL != obj && !verifyObjectPCRUD( ctx, obj, 1 )) {
+ if(NULL != obj && !verifyObjectPCRUD( ctx, class_def, obj, 1 )) {
jsonObjectFree( obj );
growing_buffer* msg = buffer_init( 128 );
dbhandle = writehandle;
char* core_class = osrfHashGet( class_meta, "classname" );
+ osrfLogDebug( OSRF_LOG_MARK, "entering doFieldmapperSearch() with core_class %s", core_class );
+
char* pkey = osrfHashGet( class_meta, "primarykey" );
+ char *inside_verify = osrfHashGet( (osrfHash*) ctx->method->userData, "inside_verify" );
+ int need_to_verify = 1;
+
+ if (inside_verify)
+ need_to_verify = !atoi(inside_verify);
+
const jsonObject* _tmp;
+ // XXX This can be redundant with another instance of the same test that happens
+ // within the functions that call doFieldmapperSearch(), but we have it here to
+ // prevent any non-pcrud-controlled classes from being fleshed on.
+ //
+ // TODO To avoid redundancy, move this block to right before we recurse,
+ // and change the class we're checking to the one we're /about/ to search for,
+ // not the one we're currently searching for.
+ if (!osrfStringArrayContains(osrfHashGet(class_meta, "controller"), modulename)) {
+ osrfLogInfo(OSRF_LOG_MARK, "%s is not listed as a controller for %s, moving on",
+ modulename, core_class);
+ return jsonNewObjectType( JSON_ARRAY ); /* empty */
+ }
+
char* sql = buildSELECT( where_hash, query_hash, class_meta, ctx );
if( !sql ) {
osrfLogDebug( OSRF_LOG_MARK, "Problem building query, returning NULL" );
jsonObjectFree( row_obj );
free( pkey_val );
} else {
- osrfHashSet( dedup, pkey_val, pkey_val );
- jsonObjectPush( res_list, row_obj );
+ if( !enforce_pcrud || !need_to_verify ||
+ verifyObjectPCRUD( ctx, class_meta, row_obj, 1 /* not at all sure about this 1 */ )) {
+ osrfHashSet( dedup, pkey_val, pkey_val );
+ jsonObjectPush( res_list, row_obj );
+ }
}
} while( dbi_result_next_row( result ));
osrfHashFree( dedup );
free( sql );
// If we're asked to flesh, and there's anything to flesh, then flesh it
- // (but not for PCRUD, lest the user to bypass permissions by fleshing
- // something that he has no permission to look at).
- if( res_list->size && query_hash && ! enforce_pcrud ) {
+ // (formerly we would skip fleshing if in pcrud mode, but now we support
+ // fleshing even in PCRUD).
+ if( res_list->size && query_hash ) {
_tmp = jsonObjectGetKeyConst( query_hash, "flesh" );
if( _tmp ) {
// Get the flesh depth
id = oilsFMGetString( jsonObjectGetIndex(ctx->params, _obj_pos), pkey );
} else {
- if( enforce_pcrud && !verifyObjectPCRUD( ctx, NULL, 1 )) {
+ if( enforce_pcrud && !verifyObjectPCRUD( ctx, meta, NULL, 1 )) {
osrfAppRespondComplete( ctx, NULL );
return -1;
}