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