#define _POSIX_C_SOURCE 200809L #include #include #include #include "app.h" #include "http.h" #include "log.h" #define CLIENT_NAME "ap_client" #define REGISTER_URL "https://%s/api/v1/apps" 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 gs_app *get_register_resp(const char *data) { struct gs_app *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 gs_app)); resp->client_id = strdup(json_string_value(cid)); resp->client_secret = strdup(json_string_value(csec)); json_decref(json_root); return resp; } struct gs_app *gs_app_register(const char *domain) { char *url, *req_data, *resp_data; struct gs_app *resp; if (!domain || !*domain) { gs_log(GS_WARNING, "gs_app_register", "invalid argument"); return NULL; } url = get_register_url(domain); if (!url) { gs_log(GS_WARNING, "gs_app_register", "invalid argument"); return NULL; } req_data = get_register_req(); if (!req_data) { free(url); return NULL; } resp_data = gs_http_post(url, NULL, req_data); free(url); free(req_data); if (!resp_data) { gs_log(GS_WARNING, "gs_app_register", "register request failed"); return NULL; } resp = get_register_resp(resp_data); free(resp_data); if (!resp) { gs_log(GS_WARNING, "gs_app_register", "invalid response"); return NULL; } return resp; }