#define _POSIX_C_SOURCE 200809L #include #include #include #include #include "http.h" #include "config.h" #include "log.h" #define CLIENT_NAME "ap_client" #define REGISTER_URL "https://%s/api/v1/apps" struct register_response { char *client_id; char *client_secret; }; static char *get_register_url(const char *domain) { char *url; size_t size; size = strlen(REGISTER_URL) + strlen(domain) - 1; url = malloc(size); if (!url) { err(1, NULL); return NULL; } sprintf(url, REGISTER_URL, domain); return url; } static char *get_register_req() { char *req; json_t *json_root; json_root = json_pack_ex(NULL, 1, "{s:s, s:s, s:s}", "client_name", CLIENT_NAME, "redirect_uris", "urn:ietf:wg:oauth:2.0:oob", "scopes", "read write push"); if (!json_root) { return NULL; } req = json_dumps(json_root, 0); json_decref(json_root); return req; } static struct register_response *get_register_resp(const char *data) { struct register_response *resp; json_t *json_root; json_t *cid, *csec; json_root = json_loads(data, 0, NULL); if (!json_root) { return NULL; } if (!json_is_object(json_root)) { json_decref(json_root); return NULL; } cid = json_object_get(json_root, "client_id"); csec = json_object_get(json_root, "client_secret"); if (!json_is_string(cid) || !json_is_string(csec)) { json_decref(json_root); return NULL; } resp = calloc(1, sizeof(struct register_response)); resp->client_id = strdup(json_string_value(cid)); resp->client_secret = strdup(json_string_value(csec)); json_decref(json_root); return resp; } int register_app(const char *domain) { char *url, *req_data, *resp_data; struct register_response *resp; if (!domain || !*domain) { log_msg(LOG_WARNING, "register_app", "invalid argument"); return -1; } url = get_register_url(domain); if (!url) { return -1; } req_data = get_register_req(); if (!req_data) { free(url); return -1; } resp_data = post_request(url, req_data); free(url); free(req_data); if (!resp_data) { log_msg(LOG_WARNING, "register_app", "register request failed"); return -1; } resp = get_register_resp(resp_data); free(resp_data); if (!resp) { log_msg(LOG_WARNING, "register_app", "invalid response"); return -1; } config_set_client_id(resp->client_id); config_set_client_secret(resp->client_secret); config_set_instance_url(domain); free(resp->client_id); free(resp->client_secret); free(resp); return 0; }