diff options
Diffstat (limited to 'libgs/src/auth.c')
-rw-r--r-- | libgs/src/auth.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/libgs/src/auth.c b/libgs/src/auth.c new file mode 100644 index 0000000..88ab7b7 --- /dev/null +++ b/libgs/src/auth.c @@ -0,0 +1,109 @@ +#define _POSIX_C_SOURCE 200809L +#include <err.h> +#include <string.h> +#include <jansson.h> +#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; +} |