diff options
author | Roberto Hueso Gómez <rhueso@soleta.eu> | 2020-07-06 17:26:40 +0200 |
---|---|---|
committer | OpenGnSys Support Team <soporte-og@soleta.eu> | 2020-07-06 17:27:33 +0200 |
commit | 33b0c6f694c3365e6280b01d9253aefa892075e9 (patch) | |
tree | 2a5be232ba5edc587423f97b5265d86e065c4781 | |
parent | 96b02b5424db61c32386c48fe05ec3375d8a84f5 (diff) |
Add POST /modes REST request
This patch implements HTTP POST /modes request which can change the mode of any
particular scope.
Request: POST /modes
{
"scope": {"id": 1,
"type": "computer"},
"mode": "pxe"
}
Response: 200 OK
-rw-r--r-- | src/json.c | 29 | ||||
-rw-r--r-- | src/json.h | 11 | ||||
-rw-r--r-- | src/rest.c | 98 |
3 files changed, 136 insertions, 2 deletions
@@ -39,6 +39,35 @@ int og_json_parse_bool(json_t *element, bool *value) return 0; } +int og_json_parse_scope(json_t *element, struct og_scope *scope, + const uint64_t required_flags) +{ + uint64_t flags = 0UL; + const char *key; + json_t *value; + int err = 0; + + json_object_foreach(element, key, value) { + if (!strcmp(key, "id")) { + err = og_json_parse_uint(value, &scope->id); + flags |= OG_PARAM_SCOPE_ID; + } else if (!strcmp(key, "type")) { + err = og_json_parse_string(value, &scope->type); + flags |= OG_PARAM_SCOPE_TYPE; + } else { + err = -1; + } + + if (err < 0) + return err; + } + + if (flags != required_flags) + return -1; + + return err; +} + int og_json_parse_partition(json_t *element, struct og_partition *part, uint64_t required_flags) { @@ -50,6 +50,17 @@ struct og_sync_params { const char *method; }; +#define OG_PARAM_SCOPE_ID (1UL << 0) +#define OG_PARAM_SCOPE_TYPE (1UL << 1) + +struct og_scope { + uint32_t id; + const char *type; +}; + +int og_json_parse_scope(json_t *element, struct og_scope *scope, + const uint64_t required_flags); + struct og_msg_params { const char *ips_array[OG_CLIENTS_MAX]; const char *mac_array[OG_CLIENTS_MAX]; @@ -110,6 +110,8 @@ static bool og_send_cmd(char *ips_array[], int ips_array_len, #define OG_REST_PARAM_TIME_AM_PM (1UL << 38) #define OG_REST_PARAM_TIME_MINUTES (1UL << 39) #define OG_REST_PARAM_NETMASK (1UL << 40) +#define OG_REST_PARAM_SCOPE (1UL << 41) +#define OG_REST_PARAM_MODE (1UL << 42) static LIST_HEAD(client_list); @@ -162,6 +164,12 @@ static bool og_msg_params_validate(const struct og_msg_params *params, return (params->flags & flags) == flags; } +static bool og_flags_validate(const uint64_t flags, + const uint64_t required_flags) +{ + return (flags & required_flags) == required_flags; +} + static int og_json_parse_clients(json_t *element, struct og_msg_params *params) { unsigned int i; @@ -898,6 +906,84 @@ static int og_cmd_get_modes(json_t *element, struct og_msg_params *params, return 0; } +static int og_cmd_post_modes(json_t *element, struct og_msg_params *params) +{ + struct og_scope scope = {}; + const char *mode_str; + struct og_dbi *dbi; + const char *msglog; + uint64_t flags = 0; + dbi_result result; + const char *key; + json_t *value; + int err = 0; + + json_object_foreach(element, key, value) { + if (!strcmp(key, "scope")) { + err = og_json_parse_scope(value, &scope, + OG_PARAM_SCOPE_ID | + OG_PARAM_SCOPE_TYPE); + flags |= OG_REST_PARAM_SCOPE; + } else if (!strcmp(key, "mode")) { + err = og_json_parse_string(value, &mode_str); + flags |= OG_REST_PARAM_MODE; + } else { + err = -1; + } + + if (err < 0) + break; + } + + if (!og_flags_validate(flags, OG_REST_PARAM_SCOPE | + OG_REST_PARAM_MODE)) + return -1; + + dbi = og_dbi_open(&dbi_config); + if (!dbi) { + syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", + __func__, __LINE__); + return -1; + } + + if (!strcmp(scope.type, "computer")) { + result = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores SET arranque='%s' " + "WHERE idordenador=%u", + mode_str, scope.id); + } else if (!strcmp(scope.type, "room")) { + result = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores SET arranque='%s' " + "WHERE idaula=%u", + mode_str, scope.id); + } else if (!strcmp(scope.type, "center")) { + result = dbi_conn_queryf(dbi->conn, + "UPDATE ordenadores SET arranque='%s' " + "INNER JOIN aulas ON " + "ordenadores.idaula=aulas.idcentro " + "WHERE aulas.idcentro=%u", + mode_str, scope.id); + } else { + syslog(LOG_ERR, "unknown scope type (%s:%d)\n", + __func__, __LINE__); + og_dbi_close(dbi); + return -1; + } + + if (!result) { + dbi_conn_error(dbi->conn, &msglog); + syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", + __func__, __LINE__, msglog); + og_dbi_close(dbi); + return -1; + } + + dbi_result_free(result); + og_dbi_close(dbi); + + return 0; +} + static int og_cmd_stop(json_t *element, struct og_msg_params *params) { const char *key; @@ -3188,10 +3274,18 @@ int og_client_state_process_payload_rest(struct og_client *cli) } err = og_cmd_reboot(root, ¶ms); } else if (!strncmp(cmd, "modes", strlen("modes"))) { - if (method != OG_METHOD_GET) + if (method != OG_METHOD_GET && method != OG_METHOD_POST) return og_client_method_not_found(cli); - err = og_cmd_get_modes(root, ¶ms, buf_reply); + if (method == OG_METHOD_POST && !root) { + syslog(LOG_ERR, "command modes with no payload\n"); + return og_client_bad_request(cli); + } + + if (method == OG_METHOD_GET) + err = og_cmd_get_modes(root, ¶ms, buf_reply); + else if (method == OG_METHOD_POST) + err = og_cmd_post_modes(root, ¶ms); } else if (!strncmp(cmd, "stop", strlen("stop"))) { if (method != OG_METHOD_POST) return og_client_method_not_found(cli); |