annotate connectors/store.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
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 static boolean execute(Connector_Store *store, const char *sql)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 return store && store->connection &&
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 Deita_Query_Execute_Update(store->connection, sql) >= 0;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 static boolean update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 Connector_Store *store, const char *sql, int32 count, const char **values)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 return store && store->connection &&
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 Deita_Query_Execute_Update_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 store->connection, sql, count, values) >= 0;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 boolean Connector_Store_Open(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 Connector_Store *store, const char *database_path,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 const Connector_Master_Key *master_key)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 if (!store || !database_path || !master_key)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 memset(store, 0, sizeof(*store));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 store->connection = Deita_Connection_Create(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 DEITA_DATABASE_TYPE_SQLITE3, database_path);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 if (!store->connection)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 store->master_key = *master_key;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 return Connector_Store_Migrate(store);
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 void Connector_Store_Close(Connector_Store *store)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 if (!store)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 return;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 if (store->connection)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 Deita_Connection_Close(store->connection);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 memset(store, 0, sizeof(*store));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 boolean Connector_Store_Migrate(Connector_Store *store)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 static const char *migration =
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 "BEGIN;"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 "CREATE TABLE IF NOT EXISTS connector_migrations("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 "version INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL);"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 "CREATE TABLE IF NOT EXISTS connector_oauth_states("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 "state TEXT PRIMARY KEY, user_id TEXT NOT NULL, verifier TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 "expires_at INTEGER NOT NULL, consumed_at INTEGER);"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 "CREATE TABLE IF NOT EXISTS connector_accounts("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 "account_id TEXT PRIMARY KEY, user_id TEXT NOT NULL, provider TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 "provider_subject TEXT NOT NULL, email TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 "access_token_enc TEXT NOT NULL, refresh_token_enc TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 "expires_at INTEGER NOT NULL, scopes TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 "UNIQUE(user_id, provider, provider_subject));"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 "CREATE INDEX IF NOT EXISTS connector_accounts_owner "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 "ON connector_accounts(user_id, account_id);"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 "CREATE TABLE IF NOT EXISTS connector_policies("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 "user_id TEXT NOT NULL, action TEXT NOT NULL, policy INTEGER NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 "PRIMARY KEY(user_id, action));"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 "CREATE TABLE IF NOT EXISTS connector_confirmations("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 "token TEXT PRIMARY KEY, user_id TEXT NOT NULL, digest TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 "expires_at INTEGER NOT NULL, consumed_at INTEGER);"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 "CREATE TABLE IF NOT EXISTS connector_idempotency("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 "user_id TEXT NOT NULL, idem_key TEXT NOT NULL, digest TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 "status INTEGER NOT NULL, response_body TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 "created_at INTEGER NOT NULL DEFAULT (unixepoch()),"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 "PRIMARY KEY(user_id, idem_key));"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 "CREATE TABLE IF NOT EXISTS connector_audit("
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 "id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 "account_id TEXT NOT NULL, operation TEXT NOT NULL, digest TEXT NOT NULL,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 "status INTEGER NOT NULL, created_at INTEGER NOT NULL DEFAULT (unixepoch()));"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 "INSERT OR IGNORE INTO connector_migrations(version, applied_at)"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 "VALUES(1, unixepoch());"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 "COMMIT;";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 return execute(store, "PRAGMA foreign_keys=ON;") &&
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 execute(store, migration);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 boolean Connector_Store_Create_State(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 Connector_Store *store, const char *user_id, const Connector_OAuth_Start *start,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 int64 expires_at)
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 char expiry[32];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 snprintf(expiry, sizeof(expiry), "%lld", expires_at);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 const char *values[] = {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 start ? start->state : NULL, user_id,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 start ? start->code_verifier : NULL, expiry
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 };
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 return start && user_id && update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 "INSERT INTO connector_oauth_states"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 "(state,user_id,verifier,expires_at) VALUES(?,?,?,?)",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 4, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 boolean Connector_Store_Consume_State(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 Connector_Store *store, const char *user_id, const char *state, int64 now,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 char *verifier, size_t verifier_size)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 if (!store || !user_id || !state || !verifier || verifier_size == 0)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 char now_text[32];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 snprintf(now_text, sizeof(now_text), "%lld", now);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 const char *values[] = {state, user_id, now_text};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 Dowa_Arena *arena = Dowa_Arena_Create(4096);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 "SELECT verifier FROM connector_oauth_states "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 "WHERE state=? AND user_id=? AND consumed_at IS NULL AND expires_at>=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 3, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 boolean found = result && Deita_Result_Set_Next(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 if (found) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 const char *value = Deita_Result_Set_Get_Text(result, 0);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 if (!value || strlen(value) >= verifier_size)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 found = FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 else
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 strcpy(verifier, value);
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 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 if (!found)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 const char *consume_values[] = {now_text, state, user_id};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 return Deita_Query_Execute_Update_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 "UPDATE connector_oauth_states SET consumed_at=? "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 "WHERE state=? AND user_id=? AND consumed_at IS NULL",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 3, consume_values) == 1;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 boolean Connector_Store_Save_Account(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 Connector_Store *store, const Connector_Account *account)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 if (!store || !account || !account->account_id[0] || !account->user_id[0])
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 char access[4096], refresh[4096], expires[32];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 if (!Connector_Encrypt(&store->master_key, account->access_token, access,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 sizeof(access)) ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 !Connector_Encrypt(&store->master_key, account->refresh_token, refresh,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 sizeof(refresh)))
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 snprintf(expires, sizeof(expires), "%lld", account->expires_at);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 const char *values[] = {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 account->account_id, account->user_id, account->provider,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 account->provider_subject, account->email, access, refresh, expires,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 account->scopes
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 return update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 "INSERT INTO connector_accounts(account_id,user_id,provider,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 "provider_subject,email,access_token_enc,refresh_token_enc,expires_at,scopes)"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 "VALUES(?,?,?,?,?,?,?,?,?) ON CONFLICT(account_id) DO UPDATE SET "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 "email=excluded.email,access_token_enc=excluded.access_token_enc,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 "refresh_token_enc=excluded.refresh_token_enc,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 "expires_at=excluded.expires_at,scopes=excluded.scopes "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 "WHERE connector_accounts.user_id=excluded.user_id",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 9, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 boolean Connector_Store_Get_Account(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 Connector_Store *store, const char *user_id, const char *account_id,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 Connector_Account *account)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 if (!store || !user_id || !account_id || !account)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 const char *values[] = {user_id, account_id};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 Dowa_Arena *arena = Dowa_Arena_Create(16384);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 "SELECT account_id,user_id,provider,provider_subject,email,"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 "access_token_enc,refresh_token_enc,expires_at,scopes "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 "FROM connector_accounts WHERE user_id=? AND account_id=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 2, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 boolean found = result && Deita_Result_Set_Next(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 if (found) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 memset(account, 0, sizeof(*account));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 #define COPY_COLUMN(field, index) do { \
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 const char *value = Deita_Result_Set_Get_Text(result, index); \
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184 if (!value || strlen(value) >= sizeof(account->field)) found = FALSE; \
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 else strcpy(account->field, value); \
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 } while (0)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 COPY_COLUMN(account_id, 0);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 COPY_COLUMN(user_id, 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 COPY_COLUMN(provider, 2);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 COPY_COLUMN(provider_subject, 3);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 COPY_COLUMN(email, 4);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 const char *access = Deita_Result_Set_Get_Text(result, 5);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 const char *refresh = Deita_Result_Set_Get_Text(result, 6);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 account->expires_at = Deita_Result_Set_Get_Integer(result, 7);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195 COPY_COLUMN(scopes, 8);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196 if (!access || !refresh ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 !Connector_Decrypt(&store->master_key, access, account->access_token,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 sizeof(account->access_token)) ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 !Connector_Decrypt(&store->master_key, refresh, account->refresh_token,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 sizeof(account->refresh_token)))
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201 found = FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 #undef COPY_COLUMN
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207 return found;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210 boolean Connector_Store_List_Accounts(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 Connector_Store *store, const char *user_id,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 Connector_Account_Summary **accounts, Dowa_Arena *arena)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214 if (!store || !user_id || !accounts || !arena)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 *accounts = NULL;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 const char *values[] = {user_id};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 "SELECT account_id,provider,email,expires_at,scopes "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 "FROM connector_accounts WHERE user_id=? ORDER BY provider,email",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
222 1, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
223 if (!result || Deita_Result_Set_Has_Error(result)) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
224 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
225 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228 while (Deita_Result_Set_Next(result)) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 Connector_Account_Summary account = {0};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 const char *account_id = Deita_Result_Set_Get_Text(result, 0);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231 const char *provider = Deita_Result_Set_Get_Text(result, 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 const char *email = Deita_Result_Set_Get_Text(result, 2);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 const char *scopes = Deita_Result_Set_Get_Text(result, 4);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234 if (!account_id || !provider || !email || !scopes ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 strlen(account_id) >= sizeof(account.account_id) ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 strlen(provider) >= sizeof(account.provider) ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237 strlen(email) >= sizeof(account.email) ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 strlen(scopes) >= sizeof(account.scopes)) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
239 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 return FALSE;
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 strcpy(account.account_id, account_id);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
243 strcpy(account.provider, provider);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
244 strcpy(account.email, email);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
245 account.expires_at = Deita_Result_Set_Get_Integer(result, 3);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
246 strcpy(account.scopes, scopes);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
247 Dowa_Array_Push_Arena(*accounts, account, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
248 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
249 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
250 return TRUE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
251 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
252
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
253 boolean Connector_Store_Delete_Account(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
254 Connector_Store *store, const char *user_id, const char *account_id)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
255 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
256 const char *values[] = {user_id, account_id};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
257 return user_id && account_id &&
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
258 Deita_Query_Execute_Update_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
259 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
260 "DELETE FROM connector_accounts WHERE user_id=? AND account_id=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
261 2, values) == 1;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
262 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
263
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
264 boolean Connector_Store_Set_Policy(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
265 Connector_Store *store, const char *user_id, const char *action,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
266 Connector_Confirmation_Policy policy)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
267 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
268 char policy_text[8];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
269 snprintf(policy_text, sizeof(policy_text), "%d", policy);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
270 const char *values[] = {user_id, action, policy_text};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
271 return user_id && action && update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
272 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
273 "INSERT INTO connector_policies(user_id,action,policy) VALUES(?,?,?) "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
274 "ON CONFLICT(user_id,action) DO UPDATE SET policy=excluded.policy",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
275 3, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
276 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
277
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
278 Connector_Confirmation_Policy Connector_Store_Get_Policy(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
279 Connector_Store *store, const char *user_id, const char *action)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
280 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
281 Connector_Confirmation_Policy fallback =
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
282 action && (!strcmp(action, "gmail.send") ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
283 !strcmp(action, "drive.overwrite"))
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
284 ? CONNECTOR_CONFIRM_ALWAYS : CONNECTOR_CONFIRM_NEVER;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
285 if (!store || !user_id || !action)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
286 return fallback;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
287 const char *values[] = {user_id, action};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
288 Dowa_Arena *arena = Dowa_Arena_Create(2048);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
289 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
290 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
291 "SELECT policy FROM connector_policies WHERE user_id=? AND action=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
292 2, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
293 if (result && Deita_Result_Set_Next(result))
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
294 fallback = (Connector_Confirmation_Policy)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
295 Deita_Result_Set_Get_Integer(result, 0);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
296 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
297 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
298 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
299 return fallback;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
300 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
301
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
302 boolean Connector_Store_Create_Confirmation(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
303 Connector_Store *store, const char *user_id, const char *digest,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
304 const char *token, int64 expires_at)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
305 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
306 char expiry[32];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
307 snprintf(expiry, sizeof(expiry), "%lld", expires_at);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
308 const char *values[] = {token, user_id, digest, expiry};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
309 return token && user_id && digest && update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
310 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
311 "INSERT INTO connector_confirmations(token,user_id,digest,expires_at)"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
312 "VALUES(?,?,?,?)", 4, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
313 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
314
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
315 boolean Connector_Store_Consume_Confirmation(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
316 Connector_Store *store, const char *user_id, const char *digest,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
317 const char *token, int64 now)
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 char now_text[32];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
320 snprintf(now_text, sizeof(now_text), "%lld", now);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
321 const char *values[] = {now_text, token, user_id, digest, now_text};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
322 return token && user_id && digest &&
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
323 Deita_Query_Execute_Update_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
324 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
325 "UPDATE connector_confirmations SET consumed_at=? WHERE token=? "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
326 "AND user_id=? AND digest=? AND consumed_at IS NULL AND expires_at>=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
327 5, values) == 1;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
328 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
329
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
330 boolean Connector_Store_Get_Idempotent(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
331 Connector_Store *store, const char *user_id, const char *key,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
332 const char *digest, int32 *status, char *body, size_t body_size)
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 if (!store || !user_id || !key || !digest || !status || !body)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
335 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
336 const char *values[] = {user_id, key, digest};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
337 Dowa_Arena *arena = Dowa_Arena_Create(4096 + body_size);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
338 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
339 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
340 "SELECT status,response_body FROM connector_idempotency "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
341 "WHERE user_id=? AND idem_key=? AND digest=?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
342 3, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
343 boolean found = result && Deita_Result_Set_Next(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
344 if (found) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
345 const char *value = Deita_Result_Set_Get_Text(result, 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
346 if (!value || strlen(value) >= body_size)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
347 found = FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
348 else {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
349 *status = (int32)Deita_Result_Set_Get_Integer(result, 0);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
350 strcpy(body, value);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
351 }
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 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
354 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
355 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
356 return found;
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
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
359 boolean Connector_Store_Put_Idempotent(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
360 Connector_Store *store, const char *user_id, const char *key,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
361 const char *digest, int32 status, const char *body)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
362 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
363 char status_text[16];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
364 snprintf(status_text, sizeof(status_text), "%d", status);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
365 const char *values[] = {user_id, key, digest, status_text, body ? body : ""};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
366 return user_id && key && digest && update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
367 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
368 "INSERT OR IGNORE INTO connector_idempotency"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
369 "(user_id,idem_key,digest,status,response_body) VALUES(?,?,?,?,?)",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
370 5, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
371 }
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
372
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
373 boolean Connector_Store_Idempotency_Conflict(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
374 Connector_Store *store, const char *user_id, const char *key,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
375 const char *digest)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
376 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
377 if (!store || !user_id || !key || !digest)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
378 return FALSE;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
379 const char *values[] = {user_id, key, digest};
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
380 Dowa_Arena *arena = Dowa_Arena_Create(2048);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
381 Deita_Result_Set *result = Deita_Query_Execute_Prepared(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
382 store->connection,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
383 "SELECT 1 FROM connector_idempotency "
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
384 "WHERE user_id=? AND idem_key=? AND digest<>?",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
385 3, values, arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
386 boolean conflict = result && Deita_Result_Set_Next(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
387 if (result)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
388 Deita_Result_Set_Free(result);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
389 Dowa_Arena_Free(arena);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
390 return conflict;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
391 }
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 boolean Connector_Store_Audit(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
394 Connector_Store *store, const char *user_id, const char *account_id,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
395 const char *operation, const char *digest, int32 status)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
396 {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
397 char status_text[16];
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
398 snprintf(status_text, sizeof(status_text), "%d", status);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
399 const char *values[] = {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
400 user_id, account_id, operation, digest, status_text
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
401 };
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
402 return user_id && account_id && operation && digest && update(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
403 store,
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
404 "INSERT INTO connector_audit"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
405 "(user_id,account_id,operation,digest,status) VALUES(?,?,?,?,?)",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
406 5, values);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
407 }