#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include "string-util.h" #include "auth.h" #include "http.h" #include "config.h" #include "log.h" #define LOGIN_URL "https://%s/oauth/token" struct login_response { char *access_token; char *scope; }; static char *get_login_url(const char *domain) { char *url; size_t size; size = strlen(LOGIN_URL) + strlen(domain) - 1; url = malloc(size); if (!url) { err(1, NULL); return NULL; } sprintf(url, LOGIN_URL, domain); return url; } static char *get_login_req(const char *email, const char *password) { char *req; json_t *json_root; json_error_t error; json_root = json_pack_ex(&error, 1, "{s:s, s:s, s:s, s:s, s:s}", "client_id", config->client_id, "client_secret", config->client_secret, "grant_type", "password", "username", email, "password", password); if (!json_root) { return NULL; } req = json_dumps(json_root, 0); json_decref(json_root); return req; } static struct login_response *get_login_resp(char *data) { struct login_response *resp; json_t *json_root; json_t *access_token, *scope; json_root = json_loads(data, 0, NULL); if (!json_root) { return NULL; } if (!json_is_object(json_root)) { json_decref(json_root); return NULL; } access_token = json_object_get(json_root, "access_token"); scope = json_object_get(json_root, "scope"); if (!json_is_string(access_token) || !json_is_string(scope)) { json_decref(json_root); return NULL; } resp = calloc(1, sizeof(struct login_response)); resp->access_token = strdup(json_string_value(access_token)); resp->scope = strdup(json_string_value(scope)); json_decref(json_root); return resp; } int login(const char *email, const char *password) { char *url, *req_data, *resp_data; struct login_response *resp; if (!email || !*email || !password || !*password) { log_msg(LOG_WARNING, "login", "invalid argument"); return -1; } if (!is_registered()) { log_msg(LOG_WARNING, "login", "app not registred"); return -1; } url = get_login_url(config->instance_url); if (!url) { err(1, NULL); return -1; } req_data = get_login_req(email, password); 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", "login request failed"); return -1; } if (!resp_data) { log_msg(LOG_WARNING, "register_app", "invalid response"); return -1; } resp = get_login_resp(resp_data); free(resp_data); if (!resp) { log_msg(LOG_WARNING, "register_app", "invalid response"); return -1; } config_set_access_token(resp->access_token); /* scope = strdup(json_string_value(scope_j)); */ if (config_save()) { log_msg(LOG_WARNING, "login_call", "failed to save config"); } free(resp->access_token); free(resp->scope); free(resp); return 0; }