forked from cee-studio/orca
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reddit-oauth2.c
101 lines (88 loc) · 3.11 KB
/
reddit-oauth2.c
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
#include <string.h>
#include "reddit.h"
#include "reddit-internal.h"
ORCAcode
reddit_access_token(
struct reddit *client,
struct reddit_access_token_params *params,
struct sized_buffer *p_resp_body)
{
if (!params) {
log_error("Missing 'params'");
return ORCA_MISSING_PARAMETER;
}
if (!params->grant_type) {
log_error("Missing 'params.grant_type'");
return ORCA_MISSING_PARAMETER;
}
char query[1024];
size_t ret=0;
ret += snprintf(query, sizeof(query), "grant_type=%s", params->grant_type);
ASSERT_S(ret < sizeof(query), "Out of bounds write attempt");
if (STREQ(params->grant_type, "password")) { // script apps
if (IS_EMPTY_STRING(params->username)) {
if (!client->username.size) {
log_error("Missing 'params.username'");
return ORCA_MISSING_PARAMETER;
}
ret += snprintf(query+ret, sizeof(query)-ret, \
"&username=%.*s", (int)client->username.size, client->username.start);
}
else {
ret += snprintf(query+ret, sizeof(query)-ret, "&username=%s", params->username);
}
if (IS_EMPTY_STRING(params->password)) {
if (!client->password.size) {
log_error("Missing 'params.password'");
return ORCA_MISSING_PARAMETER;
}
ret += snprintf(query+ret, sizeof(query)-ret, \
"&password=%.*s", (int)client->password.size, client->password.start);
}
else {
ret += snprintf(query+ret, sizeof(query)-ret, "&password=%s", params->password);
}
ASSERT_S(ret < sizeof(query), "Out of bounds write attempt");
}
else if (STREQ(params->grant_type, "authorization_code")) { // web apps
if (IS_EMPTY_STRING(params->code)) {
log_error("Missing 'params.code'");
return ORCA_MISSING_PARAMETER;
}
if (IS_EMPTY_STRING(params->redirect_uri)) {
log_error("Missing 'params.redirect_uri'");
return ORCA_MISSING_PARAMETER;
}
ret += snprintf(query+ret, sizeof(query)-ret, \
"&code=%s&redirect_uri=%s", params->code, params->redirect_uri);
ASSERT_S(ret < sizeof(query), "Out of bounds write attempt");
}
else if (!STREQ(params->grant_type, "refresh_token")) {
log_error("Unknown 'grant_type' value (%s)", params->grant_type);
return ORCA_BAD_PARAMETER;
}
ua_set_url(client->adapter.ua, BASE_API_URL);
struct sized_buffer resp_body={0};
ORCAcode code;
code = reddit_adapter_run(
&client->adapter,
&resp_body,
&(struct sized_buffer){ query, ret },
HTTP_POST, "/api/v1/access_token");
char access_token[64], token_type[64];
json_extract(resp_body.start, resp_body.size,
"(access_token):.*s"
"(token_type):.*s",
sizeof(access_token), access_token,
sizeof(token_type), token_type);
char auth[256];
ret = snprintf(auth, sizeof(auth), "%s %s", token_type, access_token);
ASSERT_S(ret < sizeof(auth), "Out of bounds write attempt");
ua_reqheader_add(client->adapter.ua, "Authorization", auth);
ua_set_url(client->adapter.ua, BASE_OAUTH_URL);
if (p_resp_body)
memcpy(p_resp_body, &resp_body, sizeof(struct sized_buffer));
else
free(resp_body.start);
return code;
}