Mercurial
annotate connectors/google.c @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | |
| children |
| rev | line source |
|---|---|
|
279
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
1 #include "connectors/connector.h" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
2 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
3 #include <stdio.h> |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
4 #include <string.h> |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
5 #include <time.h> |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
6 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
7 static boolean json_is_bounded(const char *json, size_t length) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
8 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
9 if (!json || length > CONNECTOR_MAX_JSON_BYTES) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
10 return FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
11 int32 depth = 0; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
12 boolean string = FALSE, escaped = FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
13 for (size_t i = 0; i < length; ++i) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
14 char c = json[i]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
15 if (string) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
16 if (escaped) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
17 escaped = FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
18 else if (c == '\\') |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
19 escaped = TRUE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
20 else if (c == '"') |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
21 string = FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
22 } else if (c == '"') |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
23 string = TRUE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
24 else if (c == '{' || c == '[') { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
25 if (++depth > 32) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
26 return FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
27 } else if (c == '}' || c == ']') { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
28 if (--depth < 0) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
29 return FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
30 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
31 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
32 return !string && depth == 0; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
33 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
34 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
35 static Connector_Status default_transport( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
36 const Connector_HTTP_Request *request, const char *access_token, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
37 Connector_HTTP_Response *response, Dowa_Arena *arena, void *context) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
38 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
39 (void)context; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
40 if (!request || !response || !arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
41 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
42 Seobeo_Client_Request *client = Seobeo_Client_Request_Create(request->url); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
43 if (!client) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
44 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
45 Seobeo_Client_Request_Set_Method(client, request->method); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
46 Seobeo_Client_Request_Set_Timeout_Milliseconds(client, 15000); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
47 if (access_token && access_token[0]) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
48 char authorization[2300]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
49 int32 length = snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
50 authorization, sizeof(authorization), "Authorization: Bearer %s", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
51 access_token); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
52 if (length <= 0 || (size_t)length >= sizeof(authorization)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
53 Seobeo_Client_Request_Destroy(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
54 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
55 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
56 Seobeo_Client_Request_Add_Header_Array(client, authorization); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
57 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
58 if (request->content_type) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
59 char header[256]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
60 int32 length = snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
61 header, sizeof(header), "Content-Type: %s", request->content_type); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
62 if (length <= 0 || (size_t)length >= sizeof(header)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
63 Seobeo_Client_Request_Destroy(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
64 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
65 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
66 Seobeo_Client_Request_Add_Header_Array(client, header); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
67 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
68 if (request->body && request->body_length) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
69 Seobeo_Client_Request_Set_Body( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
70 client, request->body, request->body_length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
71 if (request->download_path) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
72 Seobeo_Client_Request_Set_Download_Path(client, request->download_path); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
73 Seobeo_Client_Response *provider = Seobeo_Client_Request_Execute(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
74 if (!provider) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
75 Seobeo_Client_Request_Destroy(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
76 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
77 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
78 response->status_code = provider->status_code; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
79 response->body_length = provider->body_length; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
80 if (provider->body && !request->download_path) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
81 response->body = Dowa_Arena_Allocate(arena, provider->body_length + 1); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
82 if (!response->body) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
83 Seobeo_Client_Response_Destroy(provider); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
84 Seobeo_Client_Request_Destroy(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
85 return CONNECTOR_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
86 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
87 memcpy(response->body, provider->body, provider->body_length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
88 response->body[provider->body_length] = '\0'; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
89 } else |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
90 response->body = NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
91 Seobeo_Client_Response_Destroy(provider); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
92 Seobeo_Client_Request_Destroy(client); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
93 return CONNECTOR_OK; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
94 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
95 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
96 static Connector_Status transport( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
97 const Connector_Google_Config *config, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
98 const Connector_HTTP_Request *request, const char *access_token, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
99 Connector_HTTP_Response *response, Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
100 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
101 Connector_HTTP_Transport implementation = |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
102 config->transport ? config->transport : default_transport; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
103 return implementation( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
104 request, access_token, response, arena, config->transport_context); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
105 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
106 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
107 static char *url_join( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
108 Dowa_Arena *arena, const char *base, const char *path, const char *query) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
109 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
110 if (!arena || !base) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
111 return NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
112 size_t length = strlen(base) + (path ? strlen(path) : 0) + |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
113 (query && query[0] ? strlen(query) + 1 : 0) + 1; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
114 char *url = Dowa_Arena_Allocate(arena, length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
115 if (!url) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
116 return NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
117 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
118 url, length, "%s%s%s%s", base, path ? path : "", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
119 query && query[0] ? "?" : "", query && query[0] ? query : ""); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
120 return url; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
121 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
122 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
123 char *Connector_Google_Authorization_URL( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
124 const Connector_Google_Config *config, const Connector_OAuth_Start *start, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
125 Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
126 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
127 if (!config || !start || !arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
128 return NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
129 char client[1024], redirect[2048]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
130 if (!Connector_Form_Encode(config->client_id, client, sizeof(client)) || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
131 !Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
132 config->redirect_uri, redirect, sizeof(redirect))) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
133 return NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
134 const char *scopes = |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
135 "openid%20email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
136 "%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
137 "%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.compose"; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
138 size_t length = strlen(config->oauth_authorize_url) + strlen(client) + |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
139 strlen(redirect) + strlen(start->state) + strlen(start->code_challenge) + |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
140 strlen(scopes) + 256; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
141 char *url = Dowa_Arena_Allocate(arena, length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
142 if (!url) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
143 return NULL; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
144 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
145 url, length, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
146 "%s?client_id=%s&redirect_uri=%s&response_type=code&scope=%s" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
147 "&access_type=offline&prompt=consent&state=%s" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
148 "&code_challenge=%s&code_challenge_method=S256", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
149 config->oauth_authorize_url, client, redirect, scopes, start->state, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
150 start->code_challenge); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
151 return url; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
152 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
153 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
154 static Connector_Status token_request( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
155 const Connector_Google_Config *config, const char *body, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
156 Connector_HTTP_Response *response, Connector_Provider_Error *error, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
157 Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
158 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
159 Connector_HTTP_Request request = { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
160 .method = "POST", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
161 .url = config->oauth_token_url, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
162 .content_type = "application/x-www-form-urlencoded", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
163 .body = body, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
164 .body_length = strlen(body), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
165 .download_path = NULL |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
166 }; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
167 Connector_Status status = transport( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
168 config, &request, NULL, response, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
169 if (status != CONNECTOR_OK) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
170 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
171 snprintf(error->code, sizeof(error->code), "transport_error"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
172 return status; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
173 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
174 if (response->status_code >= 200 && response->status_code < 300) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
175 return CONNECTOR_OK; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
176 if (error) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
177 error->http_status = response->status_code; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
178 snprintf(error->code, sizeof(error->code), "token_endpoint_error"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
179 if (json_is_bounded(response->body, response->body_length)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
180 Dowa_JSON_Value parsed = Dowa_JSON_Parse( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
181 response->body, (int32)response->body_length, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
182 if (parsed.type == DOWA_JSON_OBJECT) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
183 char *code = Dowa_JSON_Get_String(parsed.object_val, "error"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
184 char *description = |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
185 Dowa_JSON_Get_String(parsed.object_val, "error_description"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
186 if (code) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
187 snprintf(error->code, sizeof(error->code), "%s", code); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
188 if (description) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
189 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
190 error->description, sizeof(error->description), "%s", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
191 description); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
192 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
193 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
194 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
195 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
196 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
197 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
198 static boolean copy_json_string( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
199 Dowa_JSON_Entry *object, const char *key, char *output, size_t output_size) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
200 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
201 char *value = Dowa_JSON_Get_String(object, key); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
202 if (!value || strlen(value) >= output_size) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
203 return FALSE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
204 strcpy(output, value); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
205 return TRUE; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
206 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
207 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
208 Connector_Status Connector_Google_Exchange_Code( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
209 const Connector_Google_Config *config, const char *code, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
210 const char *verifier, Connector_Account *account, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
211 Connector_Provider_Error *error, Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
212 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
213 if (!config || !code || !verifier || !account || !arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
214 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
215 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
216 memset(error, 0, sizeof(*error)); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
217 char encoded_code[4096], encoded_verifier[512], encoded_client[1024]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
218 char encoded_secret[2048], encoded_redirect[2048]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
219 if (!Connector_Form_Encode(code, encoded_code, sizeof(encoded_code))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
220 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
221 snprintf(error->code, sizeof(error->code), "encode_code_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
222 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
223 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
224 if (!Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
225 verifier, encoded_verifier, sizeof(encoded_verifier))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
226 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
227 snprintf(error->code, sizeof(error->code), "encode_verifier_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
228 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
229 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
230 if (!Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
231 config->client_id, encoded_client, sizeof(encoded_client))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
232 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
233 snprintf(error->code, sizeof(error->code), "encode_client_id_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
234 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
235 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
236 if (!Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
237 config->client_secret, encoded_secret, sizeof(encoded_secret))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
238 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
239 snprintf(error->code, sizeof(error->code), "encode_client_secret_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
240 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
241 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
242 if (!Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
243 config->redirect_uri, encoded_redirect, sizeof(encoded_redirect))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
244 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
245 snprintf(error->code, sizeof(error->code), "encode_redirect_uri_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
246 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
247 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
248 char body[12288]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
249 int32 body_length = snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
250 body, sizeof(body), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
251 "code=%s&client_id=%s&client_secret=%s&redirect_uri=%s" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
252 "&code_verifier=%s&grant_type=authorization_code", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
253 encoded_code, encoded_client, encoded_secret, encoded_redirect, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
254 encoded_verifier); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
255 if (body_length <= 0 || (size_t)body_length >= sizeof(body)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
256 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
257 snprintf(error->code, sizeof(error->code), "token_request_too_large"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
258 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
259 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
260 Connector_HTTP_Response token = {0}; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
261 Connector_Status status = token_request(config, body, &token, error, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
262 if (status != CONNECTOR_OK) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
263 return status; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
264 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
265 error->http_status = token.status_code; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
266 if (!token.body || token.body_length == 0) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
267 if (error) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
268 snprintf(error->code, sizeof(error->code), "empty_token_response"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
269 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
270 error->description, sizeof(error->description), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
271 "Google token endpoint returned no response body"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
272 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
273 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
274 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
275 if (!json_is_bounded(token.body, token.body_length)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
276 if (error) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
277 snprintf(error->code, sizeof(error->code), "invalid_token_body"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
278 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
279 error->description, sizeof(error->description), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
280 "Google token response was not bounded JSON (%zu bytes)", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
281 token.body_length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
282 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
283 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
284 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
285 Dowa_JSON_Value parsed = Dowa_JSON_Parse( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
286 token.body, (int32)token.body_length, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
287 if (parsed.type != DOWA_JSON_OBJECT) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
288 if (error) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
289 snprintf(error->code, sizeof(error->code), "invalid_token_json"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
290 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
291 error->description, sizeof(error->description), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
292 "Google token response JSON could not be parsed (%zu bytes)", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
293 token.body_length); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
294 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
295 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
296 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
297 Dowa_JSON_Entry *object = parsed.object_val; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
298 memset(account, 0, sizeof(*account)); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
299 strcpy(account->provider, "google"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
300 if (!copy_json_string( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
301 object, "access_token", account->access_token, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
302 sizeof(account->access_token))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
303 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
304 snprintf(error->code, sizeof(error->code), "invalid_token_response"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
305 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
306 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
307 char *refresh = Dowa_JSON_Get_String(object, "refresh_token"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
308 if (refresh && strlen(refresh) < sizeof(account->refresh_token)) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
309 strcpy(account->refresh_token, refresh); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
310 char *scope = Dowa_JSON_Get_String(object, "scope"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
311 if (scope && strlen(scope) < sizeof(account->scopes)) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
312 strcpy(account->scopes, scope); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
313 double expires = Dowa_JSON_Get_Number(object, "expires_in"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
314 account->expires_at = (int64)time(NULL) + (int64)expires; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
315 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
316 Connector_HTTP_Request identity_request = { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
317 .method = "GET", .url = config->identity_url |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
318 }; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
319 Connector_HTTP_Response identity = {0}; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
320 status = transport( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
321 config, &identity_request, account->access_token, &identity, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
322 if (status != CONNECTOR_OK || identity.status_code < 200 || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
323 identity.status_code >= 300 || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
324 !json_is_bounded(identity.body, identity.body_length)) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
325 if (error) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
326 error->http_status = identity.status_code; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
327 snprintf(error->code, sizeof(error->code), "userinfo_failed"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
328 snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
329 error->description, sizeof(error->description), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
330 "Google user-info lookup failed after token exchange"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
331 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
332 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
333 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
334 parsed = Dowa_JSON_Parse( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
335 identity.body, (int32)identity.body_length, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
336 if (parsed.type != DOWA_JSON_OBJECT) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
337 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
338 object = parsed.object_val; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
339 if (!copy_json_string( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
340 object, "sub", account->provider_subject, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
341 sizeof(account->provider_subject)) || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
342 !copy_json_string(object, "email", account->email, sizeof(account->email))) { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
343 if (error) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
344 snprintf(error->code, sizeof(error->code), "invalid_userinfo_response"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
345 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
346 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
347 int32 written = snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
348 account->account_id, sizeof(account->account_id), "google:%s", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
349 account->provider_subject); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
350 return written > 0 && (size_t)written < sizeof(account->account_id) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
351 ? CONNECTOR_OK : CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
352 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
353 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
354 Connector_Status Connector_Google_Refresh( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
355 const Connector_Google_Config *config, Connector_Account *account, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
356 Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
357 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
358 if (!config || !account || !account->refresh_token[0] || !arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
359 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
360 char refresh[4096], client[1024], secret[2048], body[8192]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
361 if (!Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
362 account->refresh_token, refresh, sizeof(refresh)) || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
363 !Connector_Form_Encode(config->client_id, client, sizeof(client)) || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
364 !Connector_Form_Encode( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
365 config->client_secret, secret, sizeof(secret))) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
366 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
367 int32 length = snprintf( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
368 body, sizeof(body), |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
369 "refresh_token=%s&client_id=%s&client_secret=%s" |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
370 "&grant_type=refresh_token", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
371 refresh, client, secret); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
372 if (length <= 0 || (size_t)length >= sizeof(body)) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
373 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
374 Connector_HTTP_Response token = {0}; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
375 Connector_Status status = token_request(config, body, &token, NULL, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
376 if (status != CONNECTOR_OK || !json_is_bounded(token.body, token.body_length)) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
377 return status == CONNECTOR_OK ? CONNECTOR_PROVIDER_ERROR : status; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
378 Dowa_JSON_Value parsed = Dowa_JSON_Parse( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
379 token.body, (int32)token.body_length, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
380 if (parsed.type != DOWA_JSON_OBJECT || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
381 !copy_json_string( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
382 parsed.object_val, "access_token", account->access_token, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
383 sizeof(account->access_token))) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
384 return CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
385 account->expires_at = (int64)time(NULL) + |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
386 (int64)Dowa_JSON_Get_Number(parsed.object_val, "expires_in"); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
387 return CONNECTOR_OK; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
388 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
389 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
390 Connector_Status Connector_Google_Revoke( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
391 const Connector_Google_Config *config, const char *token, Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
392 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
393 if (!config || !token || !arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
394 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
395 char encoded[4096], body[4200]; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
396 if (!Connector_Form_Encode(token, encoded, sizeof(encoded))) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
397 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
398 snprintf(body, sizeof(body), "token=%s", encoded); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
399 Connector_HTTP_Request request = { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
400 .method = "POST", .url = config->oauth_revoke_url, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
401 .content_type = "application/x-www-form-urlencoded", |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
402 .body = body, .body_length = strlen(body) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
403 }; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
404 Connector_HTTP_Response response = {0}; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
405 Connector_Status status = transport(config, &request, NULL, &response, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
406 return status == CONNECTOR_OK && response.status_code >= 200 && |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
407 response.status_code < 300 ? CONNECTOR_OK : CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
408 } |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
409 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
410 Connector_Status Connector_Google_Execute( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
411 const Connector_Google_Config *config, Connector_Operation operation, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
412 const Connector_Provider_Request *request, const char *access_token, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
413 Connector_Provider_Response *response, Dowa_Arena *arena) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
414 { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
415 if (!config || !request || !access_token || !response || !arena || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
416 !Connector_Operation_Is_Allowed(operation) || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
417 request->body_length > CONNECTOR_MAX_JSON_BYTES) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
418 return CONNECTOR_INVALID; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
419 const char *base = operation <= CONNECTOR_OP_DRIVE_UPDATE |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
420 ? ((operation == CONNECTOR_OP_DRIVE_UPLOAD || |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
421 operation == CONNECTOR_OP_DRIVE_UPDATE) && request->body_length |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
422 ? config->drive_upload_url : config->drive_api_url) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
423 : config->gmail_api_url; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
424 char *url = url_join(arena, base, request->path, request->query); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
425 if (!url) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
426 return CONNECTOR_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
427 Connector_HTTP_Request provider_request = { |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
428 .method = request->method, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
429 .url = url, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
430 .content_type = request->content_type, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
431 .body = request->body, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
432 .body_length = request->body_length, |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
433 .download_path = request->download_path |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
434 }; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
435 Connector_HTTP_Response provider_response = {0}; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
436 Connector_Status status = transport( |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
437 config, &provider_request, access_token, &provider_response, arena); |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
438 if (status != CONNECTOR_OK) |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
439 return status; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
440 response->provider_status = provider_response.status_code; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
441 response->body = provider_response.body; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
442 response->body_length = provider_response.body_length; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
443 response->status = provider_response.status_code >= 200 && |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
444 provider_response.status_code < 300 |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
445 ? CONNECTOR_OK : CONNECTOR_PROVIDER_ERROR; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
446 return response->status; |
|
b3b547563ec7
Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
447 } |