annotate connectors/store.c @ 281:c57149ad216e default tip

Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 22:18:15 -0700
parents b3b547563ec7
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 }