mirror of https://git.48k.eu/ogserver
				
				
				
			rest: add GET,POST /image/restrict
Allow to restrict image to scope:
 POST /image/restrict
 { "image" : 49, "scopes" : [ 1,3 ] }
 response: 200 OK
This restricts image with ID 49 to scopes 1 and 3.
You can also fetch the current list of restrictions:
 GET /image/restrict
 { "image" : 49 }
 response: 200 OK
 { "image" : 49, "scopes" : [ 1,3 ] }
Existing limitations in this interface:
 - Only restriction of image to center is possible at this moment.
 - This is only used by ogCP to validate if this is possible, no existing code
   in the ogserver uses this to restrict POST image/restore.
This is a usability feature.
			
			
				master
			
			
		
							parent
							
								
									e62a55ae37
								
							
						
					
					
						commit
						e9a8f467f1
					
				
							
								
								
									
										243
									
								
								src/rest.c
								
								
								
								
							
							
						
						
									
										243
									
								
								src/rest.c
								
								
								
								
							| 
						 | 
				
			
			@ -3895,6 +3895,230 @@ static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct og_scope_image {
 | 
			
		||||
	struct list_head list;
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void og_scope_image_list_free(struct list_head *scope_list)
 | 
			
		||||
{
 | 
			
		||||
	struct og_scope_image *scope, *next;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry_safe(scope, next, scope_list, list) {
 | 
			
		||||
		list_del(&scope->list);
 | 
			
		||||
		free(scope);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int og_json_parse_scope_image_list(json_t *element, struct list_head *scope_list)
 | 
			
		||||
{
 | 
			
		||||
	struct og_scope_image *scope;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	json_t *k;
 | 
			
		||||
 | 
			
		||||
	if (json_typeof(element) != JSON_ARRAY)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < json_array_size(element); i++) {
 | 
			
		||||
		k = json_array_get(element, i);
 | 
			
		||||
		if (json_typeof(k) != JSON_INTEGER)
 | 
			
		||||
			goto err_out;
 | 
			
		||||
 | 
			
		||||
		scope = calloc(1, sizeof(struct og_scope_image));
 | 
			
		||||
		if (!scope)
 | 
			
		||||
			goto err_out;
 | 
			
		||||
 | 
			
		||||
		scope->id = json_integer_value(k);
 | 
			
		||||
 | 
			
		||||
		list_add_tail(&scope->list, scope_list);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
err_out:
 | 
			
		||||
	og_scope_image_list_free(scope_list);
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	OG_ATTR_IMAGE_ID = (1 << 0),
 | 
			
		||||
	OG_ATTR_IMAGE_SCOPE_ID = (1 << 0),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int og_cmd_image_scope_update(json_t *element, struct og_msg_params *params)
 | 
			
		||||
{
 | 
			
		||||
	struct og_scope_image *scope;
 | 
			
		||||
	LIST_HEAD(scope_list);
 | 
			
		||||
	struct og_dbi *dbi;
 | 
			
		||||
	const char *msglog;
 | 
			
		||||
	uint32_t image_id;
 | 
			
		||||
	dbi_result result;
 | 
			
		||||
	const char *key;
 | 
			
		||||
	json_t *value;
 | 
			
		||||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	if (json_typeof(element) != JSON_OBJECT)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	json_object_foreach(element, key, value) {
 | 
			
		||||
		if (!strcmp(key, "image")) {
 | 
			
		||||
			err = og_json_parse_uint(value, &image_id);
 | 
			
		||||
			params->flags |= OG_ATTR_IMAGE_ID;
 | 
			
		||||
		} else if (!strcmp(key, "scopes")) {
 | 
			
		||||
			err = og_json_parse_scope_image_list(value, &scope_list);
 | 
			
		||||
			if (err >= 0 && !list_empty(&scope_list))
 | 
			
		||||
				params->flags |= OG_ATTR_IMAGE_SCOPE_ID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!og_msg_params_validate(params, OG_ATTR_IMAGE_ID |
 | 
			
		||||
					    OG_ATTR_IMAGE_SCOPE_ID)) {
 | 
			
		||||
		og_scope_image_list_free(&scope_list);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dbi = og_dbi_open(&ogconfig.db);
 | 
			
		||||
	if (!dbi) {
 | 
			
		||||
		syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
 | 
			
		||||
		       __func__, __LINE__);
 | 
			
		||||
		og_scope_image_list_free(&scope_list);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result = dbi_conn_queryf(dbi->conn,
 | 
			
		||||
				 "DELETE FROM image_scope WHERE image_id=%d",
 | 
			
		||||
				 image_id);
 | 
			
		||||
	if (!result) {
 | 
			
		||||
		dbi_conn_error(dbi->conn, &msglog);
 | 
			
		||||
		syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
 | 
			
		||||
		       __func__, __LINE__, msglog);
 | 
			
		||||
		goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
	dbi_result_free(result);
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(scope, &scope_list, list) {
 | 
			
		||||
		result = dbi_conn_queryf(dbi->conn,
 | 
			
		||||
					 "INSERT INTO image_scope (image_id, scope_id) "
 | 
			
		||||
					 "VALUES (%d, %d)", image_id, scope->id);
 | 
			
		||||
		if (!result) {
 | 
			
		||||
			dbi_conn_error(dbi->conn, &msglog);
 | 
			
		||||
			syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
 | 
			
		||||
			       __func__, __LINE__, msglog);
 | 
			
		||||
			goto err_out;
 | 
			
		||||
		}
 | 
			
		||||
		dbi_result_free(result);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	og_dbi_close(dbi);
 | 
			
		||||
 | 
			
		||||
	og_scope_image_list_free(&scope_list);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_out:
 | 
			
		||||
	og_scope_image_list_free(&scope_list);
 | 
			
		||||
	og_dbi_close(dbi);
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static json_t *og_json_image_scope(struct og_dbi *dbi, uint32_t image_id)
 | 
			
		||||
{
 | 
			
		||||
	json_t *scope_image, *scope_array;
 | 
			
		||||
	const char *msglog;
 | 
			
		||||
	uint32_t scope_id;
 | 
			
		||||
	dbi_result result;
 | 
			
		||||
 | 
			
		||||
	result = dbi_conn_queryf(dbi->conn,
 | 
			
		||||
				 "SELECT scope_id FROM image_scope WHERE image_id = '%u'", image_id);
 | 
			
		||||
	if (!result) {
 | 
			
		||||
		dbi_conn_error(dbi->conn, &msglog);
 | 
			
		||||
		syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
 | 
			
		||||
		       __func__, __LINE__, msglog);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scope_image = json_object();
 | 
			
		||||
	if (!scope_image) {
 | 
			
		||||
		dbi_result_free(result);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	json_object_set_new(scope_image, "id", json_integer(image_id));
 | 
			
		||||
 | 
			
		||||
	scope_array = json_array();
 | 
			
		||||
	if (!scope_array) {
 | 
			
		||||
		json_decref(scope_image);
 | 
			
		||||
		dbi_result_free(result);
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (dbi_result_next_row(result)) {
 | 
			
		||||
		scope_id = dbi_result_get_uint(result, "scope_id");
 | 
			
		||||
		json_array_append_new(scope_array, json_integer(scope_id));
 | 
			
		||||
	}
 | 
			
		||||
	dbi_result_free(result);
 | 
			
		||||
 | 
			
		||||
	json_object_set_new(scope_image, "scopes", scope_array);
 | 
			
		||||
 | 
			
		||||
	return scope_image;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int og_cmd_image_scope_list(json_t *element,
 | 
			
		||||
				   struct og_msg_params *params,
 | 
			
		||||
				   char *buffer_reply)
 | 
			
		||||
{
 | 
			
		||||
	struct og_buffer og_buffer = {
 | 
			
		||||
		.data = buffer_reply
 | 
			
		||||
	};
 | 
			
		||||
	json_t *value, *scope_image;
 | 
			
		||||
	struct og_dbi *dbi;
 | 
			
		||||
	uint32_t image_id;
 | 
			
		||||
	const char *key;
 | 
			
		||||
	int err = 0;
 | 
			
		||||
 | 
			
		||||
	if (json_typeof(element) != JSON_OBJECT)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	json_object_foreach(element, key, value) {
 | 
			
		||||
		if (!strcmp(key, "image")) {
 | 
			
		||||
			err = og_json_parse_uint(value, &image_id);
 | 
			
		||||
			params->flags |= OG_ATTR_IMAGE_ID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (err < 0)
 | 
			
		||||
			return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!og_msg_params_validate(params, OG_ATTR_IMAGE_ID))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	dbi = og_dbi_open(&ogconfig.db);
 | 
			
		||||
	if (!dbi) {
 | 
			
		||||
		syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
 | 
			
		||||
		       __func__, __LINE__);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scope_image = og_json_image_scope(dbi, image_id);
 | 
			
		||||
 | 
			
		||||
	og_dbi_close(dbi);
 | 
			
		||||
 | 
			
		||||
	if (!scope_image)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	if (json_dump_callback(scope_image, og_json_dump_clients, &og_buffer, 0)) {
 | 
			
		||||
		json_decref(scope_image);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	json_decref(scope_image);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int og_dbi_client_cache_get(struct og_dbi *dbi, json_t *clients, const char *ip)
 | 
			
		||||
{
 | 
			
		||||
	const char *img_name, *msglog, *img_checksum;
 | 
			
		||||
| 
						 | 
				
			
			@ -7934,6 +8158,7 @@ struct {
 | 
			
		|||
	[OG_URI_IMAGE_UPDATE]	= { "image/update" },
 | 
			
		||||
	[OG_URI_IMAGE_RESTORE]	= { "image/restore", },
 | 
			
		||||
	[OG_URI_IMAGE_DELETE]	= { "image/delete", },
 | 
			
		||||
	[OG_URI_IMAGE_RESTRICT]	= { "image/restrict", },
 | 
			
		||||
	[OG_URI_CACHE_LIST]	= { "cache/list", },
 | 
			
		||||
	[OG_URI_CACHE_DELETE]	= { "cache/delete", },
 | 
			
		||||
	[OG_URI_PART_SETUP]	= { "setup", },
 | 
			
		||||
| 
						 | 
				
			
			@ -8530,6 +8755,24 @@ int og_client_state_process_payload_rest(struct og_client *cli)
 | 
			
		|||
			goto err_process_rest_payload;
 | 
			
		||||
		}
 | 
			
		||||
		err = og_cmd_delete_image(root, ¶ms);
 | 
			
		||||
	} else if (!strncmp(cmd, "image/restrict", strlen("image/restrict"))) {
 | 
			
		||||
		if (!root) {
 | 
			
		||||
			err = og_client_bad_request(cli);
 | 
			
		||||
			goto err_process_rest_payload;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (method) {
 | 
			
		||||
		case OG_METHOD_GET:
 | 
			
		||||
			err = og_cmd_image_scope_list(root, ¶ms, buf_reply);
 | 
			
		||||
			break;
 | 
			
		||||
		case OG_METHOD_POST:
 | 
			
		||||
			err = og_cmd_image_scope_update(root, ¶ms);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			err = og_client_method_not_found(cli);
 | 
			
		||||
			goto err_process_rest_payload;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} else if (!strncmp(cmd, "cache/list", strlen("cache/list"))) {
 | 
			
		||||
		if (method != OG_METHOD_GET) {
 | 
			
		||||
			err = og_client_method_not_found(cli);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@ enum og_cmd_type {
 | 
			
		|||
	OG_CMD_IMAGE_CREATE,
 | 
			
		||||
	OG_CMD_IMAGE_UPDATE,
 | 
			
		||||
	OG_CMD_IMAGE_RESTORE,
 | 
			
		||||
	OG_CMD_IMAGE_RESTRICT,
 | 
			
		||||
	OG_CMD_SETUP,
 | 
			
		||||
	OG_CMD_RUN_SCHEDULE,
 | 
			
		||||
	OG_CMD_IMAGES,
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +125,7 @@ enum og_rest_uri {
 | 
			
		|||
	OG_URI_IMAGE_UPDATE,
 | 
			
		||||
	OG_URI_IMAGE_RESTORE,
 | 
			
		||||
	OG_URI_IMAGE_DELETE,
 | 
			
		||||
	OG_URI_IMAGE_RESTRICT,
 | 
			
		||||
	OG_URI_CACHE_LIST,
 | 
			
		||||
	OG_URI_CACHE_DELETE,
 | 
			
		||||
	OG_URI_PART_SETUP,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								src/schema.c
								
								
								
								
							
							
						
						
									
										35
									
								
								src/schema.c
								
								
								
								
							| 
						 | 
				
			
			@ -335,6 +335,40 @@ static int og_dbi_schema_v7(struct og_dbi *dbi)
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int og_dbi_schema_v8(struct og_dbi *dbi)
 | 
			
		||||
{
 | 
			
		||||
	const char *msglog;
 | 
			
		||||
	dbi_result result;
 | 
			
		||||
 | 
			
		||||
	syslog(LOG_DEBUG, "Creating table image_scope\n");
 | 
			
		||||
	result = dbi_conn_query(dbi->conn, "CREATE TABLE `image_scope` ("
 | 
			
		||||
				"`id` int NOT NULL AUTO_INCREMENT,"
 | 
			
		||||
				"`image_id` int NOT NULL,"
 | 
			
		||||
				"`scope_id` int NOT NULL,"
 | 
			
		||||
				"PRIMARY KEY (`id`),"
 | 
			
		||||
				"FOREIGN KEY (`image_id`) REFERENCES `imagenes` (`idimagen`) ON DELETE CASCADE,"
 | 
			
		||||
				"FOREIGN KEY (`scope_id`) REFERENCES `centros` (`idcentro`) ON DELETE CASCADE"
 | 
			
		||||
				") AUTO_INCREMENT=1;");
 | 
			
		||||
	if (!result) {
 | 
			
		||||
		dbi_conn_error(dbi->conn, &msglog);
 | 
			
		||||
		syslog(LOG_INFO, "Error when creating image_scope (%s:%d) %s\n",
 | 
			
		||||
		       __func__, __LINE__, msglog);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	dbi_result_free(result);
 | 
			
		||||
 | 
			
		||||
	result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 8");
 | 
			
		||||
	if (!result) {
 | 
			
		||||
		dbi_conn_error(dbi->conn, &msglog);
 | 
			
		||||
		syslog(LOG_INFO, "Could not update version row (%s:%d) %s\n",
 | 
			
		||||
		       __func__, __LINE__, msglog);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	dbi_result_free(result);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct og_schema_version {
 | 
			
		||||
	int	version;
 | 
			
		||||
	int	(*update)(struct og_dbi *dbi);
 | 
			
		||||
| 
						 | 
				
			
			@ -346,6 +380,7 @@ static struct og_schema_version {
 | 
			
		|||
	{	.version = 5,	.update = og_dbi_schema_v5	},
 | 
			
		||||
	{	.version = 6,	.update = og_dbi_schema_v6	},
 | 
			
		||||
	{	.version = 7,	.update = og_dbi_schema_v7,	},
 | 
			
		||||
	{	.version = 8,	.update = og_dbi_schema_v8,	},
 | 
			
		||||
	{	0,		NULL				},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue