#define _POSIX_C_SOURCE 200809L #include #include #include #include "auth.h" #include "client.h" #include "log.h" #include "string-util.h" struct login_response { char *access_token; char *scope; }; static char *get_login_req(const char *client_id, const char *client_secret, 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", client_id, "client_secret", 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 gs_auth_authenticate(GSClient *c, const char *email, const char *password) { char *req_data, *resp_data; struct login_response *resp; if (!email || !*email || !password || !*password) { gs_log(GS_WARNING, "gs_auth_authenticate", "invalid argument"); return -1; } req_data = get_login_req(c->client_id, c->client_secret, email, password); if (!req_data) { gs_log(GS_WARNING, "gs_auth_authenticate", "invalid argument"); return -1; } resp_data = (char *)gs_client_do_api(c, 2, "/oauth/token", req_data); free(req_data); if (!resp_data) { gs_log(GS_WARNING, "gs_auth_authenticate", "invalid response"); return -1; } resp = get_login_resp(resp_data); free(resp_data); if (!resp) { gs_log(GS_WARNING, "gs_auth_authenticate", "invalid response"); return -1; } gs_client_set_token(c, resp->access_token); free(resp->access_token); free(resp->scope); free(resp); return 0; } bool gs_auth_is_logged_in(GSClient *c) { return c->access_token != NULL; }