diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rest.c | 243 | ||||
-rw-r--r-- | src/rest.h | 2 | ||||
-rw-r--r-- | src/schema.c | 35 |
3 files changed, 280 insertions, 0 deletions
@@ -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, diff --git a/src/schema.c b/src/schema.c index 002fd56..7390e27 100644 --- a/src/schema.c +++ b/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 }, }; |