summaryrefslogtreecommitdiff
path: root/libgs/src/auth.c
blob: 88ab7b79ae5a9fe1db77f02f87c7cc550f4f25be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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;
}