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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }