annotate auth/auth_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 04fee26ecce0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 #include "auth/auth_store.h"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 #include "deita/deita.h"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 #include <openssl/crypto.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 #include <fcntl.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 #include <limits.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 #include <pthread.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 #include <stdio.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 #include <stdlib.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 #include <string.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 #include <time.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 #include <unistd.h>
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 struct Auth_Store {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 Deita_Connection *p_connection;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 pthread_mutex_t mutex;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 /* Migration SQL */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 static const char *k_migration_v1 =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26 "CREATE TABLE IF NOT EXISTS users ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 " id TEXT PRIMARY KEY,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 " username TEXT NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 " normalized_username TEXT NOT NULL UNIQUE,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 " password_hash TEXT NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 " role TEXT NOT NULL CHECK(role IN ('admin','member')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 " status TEXT NOT NULL DEFAULT 'active'"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 " CHECK(status IN ('active','disabled')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34 " must_change_password INTEGER NOT NULL DEFAULT 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 " password_changed_at INTEGER NOT NULL DEFAULT 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 " created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 " updated_at INTEGER NOT NULL DEFAULT (strftime('%s','now'))"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 "CREATE TABLE IF NOT EXISTS auth_sessions ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 " token_digest TEXT PRIMARY KEY,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 " csrf_digest TEXT NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 " user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43 " created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 " last_seen_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 " idle_expires_at INTEGER NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 " absolute_expires_at INTEGER NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 " password_changed_at_snapshot INTEGER NOT NULL DEFAULT 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 " revoked_at INTEGER"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 "CREATE TABLE IF NOT EXISTS guest_identities ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 " id TEXT PRIMARY KEY,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 " ip_binding_digest TEXT NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 " created_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 " last_seen_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 " expires_at INTEGER NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 "CREATE TABLE IF NOT EXISTS guest_usage ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 " guest_id TEXT NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 " REFERENCES guest_identities(id) ON DELETE CASCADE,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 " window_start INTEGER NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 " count INTEGER NOT NULL DEFAULT 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 " PRIMARY KEY (guest_id, window_start)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 "CREATE TABLE IF NOT EXISTS guest_usage_reservations ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 " id INTEGER PRIMARY KEY AUTOINCREMENT,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 " guest_id TEXT NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 " REFERENCES guest_identities(id) ON DELETE CASCADE,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 " reserved_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 " expires_at INTEGER NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 "CREATE TABLE IF NOT EXISTS admin_audit_log ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 " id INTEGER PRIMARY KEY AUTOINCREMENT,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 " actor_user_id TEXT,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 " action TEXT NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 " target_user_id TEXT,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 " detail TEXT,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 " created_at INTEGER NOT NULL DEFAULT (strftime('%s','now'))"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 "CREATE INDEX IF NOT EXISTS idx_users_normalized"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 " ON users(normalized_username);"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 "CREATE INDEX IF NOT EXISTS idx_sessions_user"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82 " ON auth_sessions(user_id);"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 "CREATE INDEX IF NOT EXISTS idx_sessions_expiry"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 " ON auth_sessions(absolute_expires_at) WHERE revoked_at IS NULL;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 "CREATE INDEX IF NOT EXISTS idx_guest_expiry"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 " ON guest_identities(expires_at);"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 "CREATE INDEX IF NOT EXISTS idx_audit_created"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 " ON admin_audit_log(created_at DESC);";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 /* Internal helpers */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 static void auth__copy_text_fixed(char *dest, size_t size, const char *text)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 const char *src = text ? text : "";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 size_t n = strlen(src);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 if (n >= size)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 n = size - 1;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 memcpy(dest, src, n);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 dest[n] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 static boolean auth__generate_uuid(char output[37])
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 uint8 bytes[16];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107 int fd = open("/dev/urandom", O_RDONLY);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 size_t offset = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 ssize_t amount;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111 if (fd < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 while (offset < sizeof(bytes))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 amount = read(fd, bytes + offset, sizeof(bytes) - offset);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 if (amount <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 close(fd);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 offset += (size_t)amount;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 close(fd);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 bytes[6] = (uint8)((bytes[6] & 0x0f) | 0x40);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 bytes[8] = (uint8)((bytes[8] & 0x3f) | 0x80);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 snprintf(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 output, 37,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 bytes[0], bytes[1], bytes[2], bytes[3],
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 bytes[4], bytes[5], bytes[6], bytes[7],
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 bytes[8], bytes[9], bytes[10], bytes[11],
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 bytes[12], bytes[13], bytes[14], bytes[15]);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 static Auth_Store_Result auth__rollback(Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 Auth_Store_Result result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 Deita_Query_Execute_Update(p_store->p_connection, "ROLLBACK");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 return result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144 /* Forward declaration — implementation is in the guest quota section. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 static void auth__i64_str(char *buf, size_t size, int64 value);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 static boolean auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 const char *actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 const char *action,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 const char *target_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 const char *detail)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 /* actor_user_id and detail may be NULL — represented as empty string */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 const char *actor = actor_user_id ? actor_user_id : "";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156 const char *tgt = target_user_id ? target_user_id : "";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 const char *det = detail ? detail : "";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 const char *params[] = {actor, action, tgt, det};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 "INSERT INTO admin_audit_log"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 " (actor_user_id, action, target_user_id, detail)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 " VALUES (?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 4, params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 /* Trim to the most recent 10 000 entries. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 "DELETE FROM admin_audit_log"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 " WHERE id <= (SELECT MAX(id) FROM admin_audit_log) - 10000");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 static boolean auth__digest_is_valid(const char *digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 if (!digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 for (size_t i = 0; i < AUTH_CRYPTO_TOKEN_DIGEST_SIZE - 1; i++)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 uint8 c = (uint8)digest[i];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 if (c == '\0' ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 !((c >= '0' && c <= '9') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 (c >= 'a' && c <= 'f') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184 (c >= 'A' && c <= 'F')))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187 return digest[AUTH_CRYPTO_TOKEN_DIGEST_SIZE - 1] == '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 static boolean auth__session_arguments_are_valid(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 const char *csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195 int64 current_unix)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 if (!auth__digest_is_valid(token_digest) ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 !auth__digest_is_valid(csrf_digest) ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 current_unix < 0 || idle_ttl_secs <= 0 || absolute_ttl_secs <= 0 ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200 idle_ttl_secs > absolute_ttl_secs)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 if (current_unix > (int64)LLONG_MAX - idle_ttl_secs ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203 current_unix > (int64)LLONG_MAX - absolute_ttl_secs)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 static void auth__fill_session_record(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209 Auth_Session_Record *p_record,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214 int64 password_changed_at)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 memset(p_record, 0, sizeof(*p_record));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 auth__copy_text_fixed(p_record->user_id, sizeof(p_record->user_id), user_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218 p_record->created_at = current_unix;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219 p_record->last_seen_at = current_unix;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 p_record->idle_expires_at = current_unix + idle_ttl_secs;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 p_record->absolute_expires_at = current_unix + absolute_ttl_secs;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
222 p_record->password_changed_at_snapshot = password_changed_at;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
223 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
224
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
225 static Auth_Store_Result auth__insert_session_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 const char *csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 int64 password_changed_at)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 char created_str[32], idle_exp_str[32], abs_exp_str[32], snap_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 snprintf(created_str, sizeof(created_str), "%lld", (long long)current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237 snprintf(idle_exp_str, sizeof(idle_exp_str), "%lld",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 (long long)(current_unix + idle_ttl_secs));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
239 snprintf(abs_exp_str, sizeof(abs_exp_str), "%lld",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 (long long)(current_unix + absolute_ttl_secs));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
241 snprintf(snap_str, sizeof(snap_str), "%lld",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
242 (long long)password_changed_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
243
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
244 const char *params[] = {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
245 token_digest, csrf_digest, user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
246 created_str, created_str, idle_exp_str, abs_exp_str, snap_str
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
247 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
248 int32 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
249 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
250 "INSERT INTO auth_sessions"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
251 " (token_digest, csrf_digest, user_id,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
252 " created_at, last_seen_at, idle_expires_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
253 " absolute_expires_at, password_changed_at_snapshot)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
254 " VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
255 8, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
256 return result < 0 ? AUTH_STORE_CONFLICT : AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
257 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
258
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
259 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
260 /* Migration system */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
261 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
262
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
263 static boolean auth__apply_migration(Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
264 int32 version,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
265 const char *sql)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
266 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
267 char version_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
268 snprintf(version_str, sizeof(version_str), "%d", (int)version);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
269
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
270 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
271 p_store->p_connection, "BEGIN EXCLUSIVE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
272 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
273
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
274 /* Check if already applied. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
275 Dowa_Arena *p_arena = Dowa_Arena_Create(1024);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
276 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
277 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
278 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
279 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
280 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
281 const char *check_params[] = {version_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
282 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
283 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
284 "SELECT version FROM auth_schema_migrations WHERE version = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
285 1, check_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
286 boolean already = p_result && Deita_Result_Set_Next(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
287 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
288 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
289 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
290
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
291 if (already)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
292 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
293 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
294 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
295 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
296 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
297 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
298 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
299 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
300
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
301 /* Apply the migration. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
302 if (Deita_Query_Execute_Update(p_store->p_connection, sql) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
303 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
304 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
305 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
306 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
307
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
308 const char *ins_params[] = {version_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
309 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
310 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
311 "INSERT INTO auth_schema_migrations (version) VALUES (?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
312 1, ins_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
313 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
314 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
315 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
316 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
317
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
318 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
319 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
320 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
321 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
322 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
323 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
324 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
325
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
326 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
327 * Migration v2: extend guest quota tables.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
328 * - Backfills turns_used from the legacy count column before any new schema
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
329 * is applied, so existing usage is preserved (req 1).
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
330 * - Adds turns_used, output_tokens_used, output_tokens_reserved to guest_usage.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
331 * - Replaces guest_usage_reservations with a richer schema keyed by request_id.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
332 * The old reservations table is ephemeral (in-flight requests only), so
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
333 * dropping and recreating it is safe; legacy reservations had no token-amount
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
334 * column so output_tokens_reserved stays 0 after the replace.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
335 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
336 static const char *k_migration_v2 =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
337 "ALTER TABLE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
338 " ADD COLUMN turns_used INTEGER NOT NULL DEFAULT 0;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
339 "ALTER TABLE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
340 " ADD COLUMN output_tokens_used INTEGER NOT NULL DEFAULT 0;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
341 "ALTER TABLE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
342 " ADD COLUMN output_tokens_reserved INTEGER NOT NULL DEFAULT 0;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
343 /* Backfill turns_used from the legacy request-count column. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
344 "UPDATE guest_usage SET turns_used = count WHERE count > 0;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
345 "DROP TABLE IF EXISTS guest_usage_reservations;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
346 "CREATE TABLE IF NOT EXISTS guest_usage_reservations ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
347 " request_id TEXT PRIMARY KEY,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
348 " guest_id TEXT NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
349 " REFERENCES guest_identities(id) ON DELETE CASCADE,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
350 " window_start INTEGER NOT NULL,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
351 " output_tokens_reserved INTEGER NOT NULL DEFAULT 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
352 " reserved_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
353 " expires_at INTEGER NOT NULL"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
354 ");"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
355 "CREATE INDEX IF NOT EXISTS idx_reservations_guest"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
356 " ON guest_usage_reservations(guest_id);"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
357 "CREATE INDEX IF NOT EXISTS idx_reservations_expiry"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
358 " ON guest_usage_reservations(expires_at);"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
359 "CREATE INDEX IF NOT EXISTS idx_guest_usage_guest"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
360 " ON guest_usage(guest_id);";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
361
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
362 static boolean auth__run_migrations(Auth_Store *p_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
363 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
364 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
365 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
366 "CREATE TABLE IF NOT EXISTS auth_schema_migrations ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
367 " version INTEGER PRIMARY KEY,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
368 " applied_at INTEGER NOT NULL DEFAULT (strftime('%s','now'))"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
369 ")") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
370 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
371
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
372 if (!auth__apply_migration(p_store, 1, k_migration_v1))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
373 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
374 return auth__apply_migration(p_store, 2, k_migration_v2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
375 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
376
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
377 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
378 /* Store lifecycle */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
379 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
380
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
381 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
382 * Reap expired reservations with the mutex already held.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
383 * Run atomically in a nested SAVEPOINT to avoid interfering with any outer
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
384 * transaction (callers sometimes hold BEGIN IMMEDIATE).
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
385 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
386 static void auth__reap_expired_reservations_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
387 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
388 int64 current_unix)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
389 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
390 char now_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
391 auth__i64_str(now_str, sizeof(now_str), current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
392
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
393 /* Use a savepoint so we can run inside or outside a transaction. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
394 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
395 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
396 "SAVEPOINT reap_expired") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
397 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
398
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
399 const char *upd_params[] = {now_str, now_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
400 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
401 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
402 "UPDATE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
403 " SET output_tokens_reserved = MAX(0, output_tokens_reserved - ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
404 " SELECT COALESCE(SUM(r.output_tokens_reserved), 0)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
405 " FROM guest_usage_reservations r"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
406 " WHERE r.guest_id = guest_usage.guest_id"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
407 " AND r.window_start = guest_usage.window_start"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
408 " AND r.expires_at < ?"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
409 " ))"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
410 " WHERE output_tokens_reserved > 0"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
411 " AND EXISTS ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
412 " SELECT 1 FROM guest_usage_reservations r2"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
413 " WHERE r2.guest_id = guest_usage.guest_id"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
414 " AND r2.expires_at < ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
415 2, upd_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
416 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
417 Deita_Query_Execute_Update(p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
418 "ROLLBACK TO reap_expired");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
419 Deita_Query_Execute_Update(p_store->p_connection, "RELEASE reap_expired");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
420 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
421 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
422
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
423 const char *del_params[] = {now_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
424 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
425 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
426 "DELETE FROM guest_usage_reservations WHERE expires_at < ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
427 1, del_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
428 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
429 Deita_Query_Execute_Update(p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
430 "ROLLBACK TO reap_expired");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
431 Deita_Query_Execute_Update(p_store->p_connection, "RELEASE reap_expired");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
432 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
433 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
434
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
435 Deita_Query_Execute_Update(p_store->p_connection, "RELEASE reap_expired");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
436 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
437
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
438 Auth_Store *Auth_Store_Create(const char *database_path)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
439 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
440 if (!database_path)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
441 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
442
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
443 Auth_Store *p_store = calloc(1, sizeof(*p_store));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
444 if (!p_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
445 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
446
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
447 p_store->p_connection = Deita_Connection_Create(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
448 DEITA_DATABASE_TYPE_SQLITE3, database_path);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
449 if (!p_store->p_connection ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
450 !Deita_Connection_Is_Open(p_store->p_connection))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
451 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
452 if (p_store->p_connection)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
453 Deita_Connection_Close(p_store->p_connection);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
454 free(p_store);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
455 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
456 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
457
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
458 if (pthread_mutex_init(&p_store->mutex, NULL) != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
459 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
460 Deita_Connection_Close(p_store->p_connection);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
461 free(p_store);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
462 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
463 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
464
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
465 /* Connection-level settings — must be re-applied on every open. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
466 if (Deita_Query_Execute_Update(p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
467 "PRAGMA foreign_keys = ON;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
468 "PRAGMA journal_mode = WAL;") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
469 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
470 Auth_Store_Destroy(p_store);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
471 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
472 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
473
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
474 if (!auth__run_migrations(p_store))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
475 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
476 Auth_Store_Destroy(p_store);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
477 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
478 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
479
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
480 /* Reap any expired reservations left over from a previous run. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
481 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
482 auth__reap_expired_reservations_locked(p_store, (int64)time(NULL));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
483 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
484
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
485 return p_store;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
486 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
487
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
488 void Auth_Store_Destroy(Auth_Store *p_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
489 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
490 if (!p_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
491 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
492 if (p_store->p_connection)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
493 Deita_Connection_Close(p_store->p_connection);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
494 pthread_mutex_destroy(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
495 free(p_store);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
496 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
497
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
498 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
499 /* Username utilities */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
500 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
501
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
502 boolean Auth_Store_Normalize_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
503 const char *username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
504 char *normalized,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
505 size_t capacity)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
506 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
507 if (!username || !normalized || capacity == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
508 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
509
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
510 size_t len = strlen(username);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
511 size_t start = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
512 size_t end = len;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
513
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
514 while (start < len && username[start] == ' ')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
515 start++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
516 while (end > start && username[end - 1] == ' ')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
517 end--;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
518
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
519 size_t norm_len = end - start;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
520 if (norm_len < AUTH_STORE_USERNAME_MIN ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
521 norm_len > AUTH_STORE_USERNAME_MAX)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
522 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
523 if (capacity <= norm_len)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
524 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
525
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
526 for (size_t i = 0; i < norm_len; i++)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
527 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
528 uint8 c = (uint8)username[start + i];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
529 if (c >= 'A' && c <= 'Z')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
530 c = (uint8)(c - 'A' + 'a');
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
531 else if ((c >= 'a' && c <= 'z') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
532 (c >= '0' && c <= '9') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
533 c == '_' || c == '-' || c == '.')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
534 ; /* valid as-is */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
535 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
536 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
537 normalized[i] = (char)c;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
538 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
539 normalized[norm_len] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
540 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
541 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
542
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
543 boolean Auth_Store_Validate_Username(const char *normalized_username)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
544 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
545 if (!normalized_username)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
546 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
547 size_t i = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
548 while (normalized_username[i] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
549 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
550 if (i >= AUTH_STORE_USERNAME_MAX)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
551 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
552 uint8 c = (uint8)normalized_username[i];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
553 if (!((c >= 'a' && c <= 'z') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
554 (c >= '0' && c <= '9') ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
555 c == '_' || c == '-' || c == '.'))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
556 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
557 i++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
558 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
559 return i >= AUTH_STORE_USERNAME_MIN;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
560 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
561
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
562 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
563 /* Internal: populate Auth_User_Record from an open result set */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
564 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
565
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
566 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
567 * Columns expected (0-based):
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
568 * 0 id, 1 username, 2 normalized_username, 3 role, 4 status,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
569 * 5 must_change_password, 6 password_changed_at, 7 created_at, 8 updated_at
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
570 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
571 static void auth__read_user_record(Auth_User_Record *r,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
572 Deita_Result_Set *p)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
573 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
574 auth__copy_text_fixed(r->id, sizeof(r->id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
575 Deita_Result_Set_Get_Text(p, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
576 auth__copy_text_fixed(r->username, sizeof(r->username),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
577 Deita_Result_Set_Get_Text(p, 1));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
578 auth__copy_text_fixed(r->normalized_username,sizeof(r->normalized_username),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
579 Deita_Result_Set_Get_Text(p, 2));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
580 auth__copy_text_fixed(r->role, sizeof(r->role),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
581 Deita_Result_Set_Get_Text(p, 3));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
582 auth__copy_text_fixed(r->status, sizeof(r->status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
583 Deita_Result_Set_Get_Text(p, 4));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
584 r->must_change_password = Deita_Result_Set_Get_Integer(p, 5) ? TRUE : FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
585 r->password_changed_at = Deita_Result_Set_Get_Integer(p, 6);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
586 r->created_at = Deita_Result_Set_Get_Integer(p, 7);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
587 r->updated_at = Deita_Result_Set_Get_Integer(p, 8);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
588 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
589
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
590 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
591 /* User management */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
592 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
593
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
594 Auth_Store_Result Auth_Store_Create_User(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
595 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
596 const char *username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
597 const char *encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
598 const char *role,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
599 boolean must_change_password,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
600 char output_id[37])
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
601 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
602 if (!p_store || !username || !encoded_hash || !role || !output_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
603 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
604 if (encoded_hash[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
605 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
606 if (strcmp(role, "admin") != 0 && strcmp(role, "member") != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
607 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
608
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
609 char normalized[AUTH_STORE_USERNAME_MAX + 1];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
610 if (!Auth_Store_Normalize_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
611 username, normalized, sizeof(normalized)))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
612 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
613
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
614 if (!auth__generate_uuid(output_id))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
615 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
616
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
617 const char *mcp_str = must_change_password ? "1" : "0";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
618 const char *params[] = {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
619 output_id, username, normalized, encoded_hash, role, mcp_str
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
620 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
621
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
622 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
623 int32 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
624 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
625 "INSERT INTO users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
626 " (id, username, normalized_username, password_hash, role,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
627 " must_change_password)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
628 " VALUES (?, ?, ?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
629 6, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
630 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
631
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
632 if (result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
633 return AUTH_STORE_CONFLICT; /* most likely UNIQUE constraint on norm_name */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
634 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
635 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
636
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
637 Auth_Store_Result Auth_Store_Create_User_Audited(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
638 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
639 const char *username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
640 const char *encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
641 const char *role,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
642 boolean must_change_password,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
643 const char *actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
644 char output_id[37])
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
645 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
646 if (!p_store || !username || !encoded_hash || !role || !output_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
647 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
648 if (encoded_hash[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
649 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
650 if (strcmp(role, "admin") != 0 && strcmp(role, "member") != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
651 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
652
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
653 char normalized[AUTH_STORE_USERNAME_MAX + 1];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
654 if (!Auth_Store_Normalize_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
655 username, normalized, sizeof(normalized)))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
656 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
657 if (!auth__generate_uuid(output_id))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
658 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
659
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
660 const char *mcp_str = must_change_password ? "1" : "0";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
661 const char *params[] = {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
662 output_id, username, normalized, encoded_hash, role, mcp_str
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
663 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
664
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
665 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
666 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
667 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
668 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
669 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
670 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
671 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
672
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
673 int32 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
674 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
675 "INSERT INTO users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
676 " (id, username, normalized_username, password_hash, role,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
677 " must_change_password)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
678 " VALUES (?, ?, ?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
679 6, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
680 if (result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
681 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
682 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
683 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
684 return AUTH_STORE_CONFLICT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
685 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
686
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
687 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
688 p_store, actor_user_id, "admin_user_created", output_id, role))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
689 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
690 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
691 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
692 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
693 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
694
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
695 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
696 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
697 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
698 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
699 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
700 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
701
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
702 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
703 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
704 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
705
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
706 Auth_Store_Result Auth_Store_Bootstrap_Admin(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
707 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
708 const char *username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
709 const char *encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
710 Auth_Store_Bootstrap_Result *p_bootstrap_result,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
711 char output_id[37])
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
712 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
713 if (!p_store || !username || !encoded_hash || !p_bootstrap_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
714 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
715 if (encoded_hash[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
716 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
717
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
718 char normalized[AUTH_STORE_USERNAME_MAX + 1];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
719 if (!Auth_Store_Normalize_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
720 username, normalized, sizeof(normalized)))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
721 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
722
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
723 char id_buf[37];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
724 if (!auth__generate_uuid(id_buf))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
725 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
726
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
727 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
728
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
729 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
730 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
731 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
732 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
733 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
734 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
735
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
736 /* Check for any existing admin (active or disabled). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
737 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
738 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
739 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
740 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
741 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
742 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
743 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
744
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
745 Deita_Result_Set *p_result = Deita_Query_Execute(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
746 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
747 "SELECT id FROM users WHERE role = 'admin' LIMIT 1",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
748 p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
749 boolean admin_exists = p_result && Deita_Result_Set_Next(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
750 char existing_id[37] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
751 if (admin_exists && p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
752 auth__copy_text_fixed(existing_id, sizeof(existing_id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
753 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
754 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
755 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
756 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
757
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
758 if (admin_exists)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
759 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
760 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
761 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
762 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
763 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
764 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
765 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
766 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
767 *p_bootstrap_result = AUTH_STORE_BOOTSTRAP_ALREADY_PRESENT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
768 if (output_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
769 auth__copy_text_fixed(output_id, 37, existing_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
770 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
771 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
772
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
773 const char *params[] = {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
774 id_buf, username, normalized, encoded_hash, "admin"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
775 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
776 int32 ins = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
777 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
778 "INSERT INTO users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
779 " (id, username, normalized_username, password_hash, role)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
780 " VALUES (?, ?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
781 5, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
782 if (ins < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
783 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
784 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
785 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
786 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
787 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
788
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
789 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
790 p_store, NULL, "bootstrap_admin_created", id_buf, NULL))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
791 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
792 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
793 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
794 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
795 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
796
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
797 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
798 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
799 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
800 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
801 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
802 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
803
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
804 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
805 *p_bootstrap_result = AUTH_STORE_BOOTSTRAP_CREATED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
806 if (output_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
807 auth__copy_text_fixed(output_id, 37, id_buf);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
808 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
809 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
810
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
811 Auth_Store_Result Auth_Store_Find_User_By_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
812 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
813 const char *username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
814 Auth_User_Auth_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
815 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
816 if (!p_store || !username || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
817 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
818
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
819 char normalized[AUTH_STORE_USERNAME_MAX + 1];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
820 if (!Auth_Store_Normalize_Username(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
821 username, normalized, sizeof(normalized)))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
822 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
823
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
824 memset(p_record, 0, sizeof(*p_record));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
825
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
826 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
827 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
828 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
829
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
830 const char *params[] = {normalized};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
831 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
832 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
833 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
834 "SELECT id, username, normalized_username, role, status,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
835 " must_change_password, password_changed_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
836 " created_at, updated_at, password_hash"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
837 " FROM users WHERE normalized_username = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
838 1, params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
839 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
840 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
841 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
842 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
843 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
844 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
845 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
846 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
847 auth__read_user_record(&p_record->user, p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
848 auth__copy_text_fixed(p_record->password_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
849 sizeof(p_record->password_hash),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
850 Deita_Result_Set_Get_Text(p_result, 9));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
851 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
852 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
853 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
854 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
855 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
856
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
857 Auth_Store_Result Auth_Store_Get_User(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
858 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
859 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
860 Auth_User_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
861 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
862 if (!p_store || !user_id || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
863 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
864
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
865 memset(p_record, 0, sizeof(*p_record));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
866
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
867 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
868 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
869 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
870
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
871 const char *params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
872 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
873 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
874 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
875 "SELECT id, username, normalized_username, role, status,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
876 " must_change_password, password_changed_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
877 " created_at, updated_at"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
878 " FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
879 1, params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
880 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
881 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
882 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
883 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
884 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
885 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
886 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
887 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
888 auth__read_user_record(p_record, p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
889 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
890 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
891 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
892 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
893 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
894
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
895 Auth_Store_Result Auth_Store_List_Users(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
896 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
897 Auth_User_Record **pp_records,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
898 Dowa_Arena *p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
899 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
900 if (!p_store || !pp_records || !p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
901 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
902
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
903 *pp_records = NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
904
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
905 Dowa_Arena *p_local = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
906 if (!p_local)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
907 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
908
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
909 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
910 Deita_Result_Set *p_result = Deita_Query_Execute(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
911 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
912 "SELECT id, username, normalized_username, role, status,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
913 " must_change_password, password_changed_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
914 " created_at, updated_at"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
915 " FROM users ORDER BY created_at",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
916 p_local);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
917 if (!p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
918 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
919 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
920 Dowa_Arena_Free(p_local);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
921 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
922 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
923
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
924 Auth_User_Record *records = NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
925 while (Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
926 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
927 Auth_User_Record record;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
928 memset(&record, 0, sizeof(record));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
929 auth__read_user_record(&record, p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
930 Dowa_Array_Push_Arena(records, record, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
931 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
932 boolean err = Deita_Result_Set_Has_Error(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
933 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
934 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
935 Dowa_Arena_Free(p_local);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
936
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
937 if (err)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
938 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
939
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
940 *pp_records = records;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
941 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
942 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
943
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
944 static Auth_Store_Result auth__update_user_status(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
945 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
946 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
947 const char *new_status,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
948 const char *actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
949 boolean revoke_sessions)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
950 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
951 if (!p_store || !user_id || !new_status)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
952 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
953 if (strcmp(new_status, "active") != 0 &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
954 strcmp(new_status, "disabled") != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
955 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
956
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
957 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
958
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
959 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
960 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
961 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
962 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
963 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
964 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
965
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
966 /* Fetch current role and status. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
967 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
968 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
969 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
970 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
971 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
972 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
973 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
974 const char *sel_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
975 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
976 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
977 "SELECT role, status FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
978 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
979 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
980 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
981 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
982 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
983 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
984 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
985 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
986 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
987 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
988 char cur_role[8], cur_status[9];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
989 auth__copy_text_fixed(cur_role, sizeof(cur_role),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
990 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
991 auth__copy_text_fixed(cur_status, sizeof(cur_status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
992 Deita_Result_Set_Get_Text(p_result, 1));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
993 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
994 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
995
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
996 /* Last-admin protection: prevent disabling the final active admin. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
997 if (strcmp(new_status, "disabled") == 0 &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
998 strcmp(cur_role, "admin") == 0 &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
999 strcmp(cur_status, "active") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1000 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1001 Dowa_Arena *p_count_arena = Dowa_Arena_Create(1024);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1002 if (!p_count_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1003 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1004 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1005 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1006 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1007 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1008 p_result = Deita_Query_Execute(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1009 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1010 "SELECT COUNT(*) FROM users WHERE role = 'admin' AND status = 'active'",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1011 p_count_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1012 int64 count = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1013 if (p_result && Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1014 count = Deita_Result_Set_Get_Integer(p_result, 0);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1015 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1016 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1017 Dowa_Arena_Free(p_count_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1018
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1019 if (count <= 1)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1020 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1021 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1022 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1023 return AUTH_STORE_LAST_ADMIN;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1024 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1025 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1026
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1027 const char *upd_params[] = {new_status, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1028 int32 upd = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1029 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1030 "UPDATE users SET status = ?, updated_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1031 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1032 2, upd_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1033 if (upd <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1034 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1035 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1036 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1037 return upd < 0 ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1038 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1039
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1040 if (revoke_sessions)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1041 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1042 const char *rev_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1043 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1044 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1045 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1046 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1047 1, rev_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1048 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1049 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1050 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1051 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1052 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1053 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1054
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1055 char detail[64];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1056 snprintf(detail, sizeof(detail), "status->%s", new_status);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1057 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1058 p_store, actor_user_id, "user_status_updated", user_id, detail))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1059 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1060 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1061 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1062 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1063 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1064
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1065 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1066 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1067 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1068 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1069 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1070 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1071
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1072 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1073 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1074 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1075
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1076 Auth_Store_Result Auth_Store_Update_User_Status(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1077 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1078 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1079 const char *new_status,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1080 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1081 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1082 return auth__update_user_status(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1083 p_store, user_id, new_status, actor_user_id, FALSE);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1084 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1085
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1086 Auth_Store_Result Auth_Store_Enable_User(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1087 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1088 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1089 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1090 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1091 return auth__update_user_status(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1092 p_store, user_id, "active", actor_user_id, FALSE);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1093 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1094
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1095 Auth_Store_Result Auth_Store_Disable_User_And_Revoke_Sessions(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1096 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1097 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1098 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1099 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1100 return auth__update_user_status(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1101 p_store, user_id, "disabled", actor_user_id, TRUE);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1102 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1103
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1104 static Auth_Store_Result auth__update_user_role(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1105 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1106 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1107 const char *new_role,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1108 const char *actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1109 boolean revoke_sessions)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1110 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1111 if (!p_store || !user_id || !new_role)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1112 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1113 if (strcmp(new_role, "admin") != 0 && strcmp(new_role, "member") != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1114 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1115
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1116 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1117
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1118 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1119 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1120 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1121 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1122 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1123 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1124
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1125 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1126 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1127 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1128 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1129 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1130 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1131 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1132 const char *sel_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1133 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1134 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1135 "SELECT role, status FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1136 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1137 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1138 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1139 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1140 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1141 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1142 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1143 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1144 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1145 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1146 char cur_role[8], cur_status[9];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1147 auth__copy_text_fixed(cur_role, sizeof(cur_role),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1148 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1149 auth__copy_text_fixed(cur_status, sizeof(cur_status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1150 Deita_Result_Set_Get_Text(p_result, 1));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1151 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1152 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1153
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1154 /* Last-admin protection: prevent demoting the final active admin. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1155 if (strcmp(new_role, "member") == 0 &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1156 strcmp(cur_role, "admin") == 0 &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1157 strcmp(cur_status, "active") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1158 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1159 Dowa_Arena *p_count_arena = Dowa_Arena_Create(1024);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1160 if (!p_count_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1161 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1162 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1163 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1164 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1165 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1166 p_result = Deita_Query_Execute(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1167 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1168 "SELECT COUNT(*) FROM users WHERE role = 'admin' AND status = 'active'",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1169 p_count_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1170 int64 count = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1171 if (p_result && Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1172 count = Deita_Result_Set_Get_Integer(p_result, 0);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1173 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1174 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1175 Dowa_Arena_Free(p_count_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1176
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1177 if (count <= 1)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1178 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1179 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1180 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1181 return AUTH_STORE_LAST_ADMIN;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1182 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1183 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1184
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1185 const char *upd_params[] = {new_role, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1186 int32 upd = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1187 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1188 "UPDATE users SET role = ?, updated_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1189 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1190 2, upd_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1191 if (upd <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1192 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1193 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1194 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1195 return upd < 0 ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1196 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1197
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1198 if (revoke_sessions)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1199 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1200 const char *rev_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1201 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1202 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1203 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1204 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1205 1, rev_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1206 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1207 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1208 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1209 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1210 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1211 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1212
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1213 char detail[64];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1214 snprintf(detail, sizeof(detail), "role->%s", new_role);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1215 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1216 p_store, actor_user_id, "user_role_updated", user_id, detail))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1217 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1218 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1219 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1220 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1221 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1222
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1223 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1224 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1225 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1226 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1227 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1228 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1229
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1230 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1231 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1232 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1233
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1234 Auth_Store_Result Auth_Store_Update_User_Role(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1235 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1236 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1237 const char *new_role,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1238 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1239 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1240 return auth__update_user_role(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1241 p_store, user_id, new_role, actor_user_id, FALSE);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1242 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1243
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1244 Auth_Store_Result Auth_Store_Update_Role_And_Revoke_Sessions(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1245 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1246 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1247 const char *new_role,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1248 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1249 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1250 return auth__update_user_role(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1251 p_store, user_id, new_role, actor_user_id, TRUE);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1252 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1253
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1254 Auth_Store_Result Auth_Store_Set_Must_Change_Password(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1255 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1256 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1257 boolean value,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1258 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1259 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1260 if (!p_store || !user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1261 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1262
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1263 const char *val_str = value ? "1" : "0";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1264 const char *params[] = {val_str, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1265
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1266 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1267
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1268 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1269 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1270 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1271 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1272 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1273 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1274
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1275 int32 upd = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1276 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1277 "UPDATE users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1278 " SET must_change_password = ?, updated_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1279 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1280 2, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1281 if (upd <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1282 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1283 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1284 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1285 return upd < 0 ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1286 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1287
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1288 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1289 p_store, actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1290 value ? "must_change_password_set" : "must_change_password_cleared",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1291 user_id, NULL))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1292 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1293 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1294 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1295 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1296 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1297
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1298 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1299 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1300 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1301 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1302 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1303 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1304
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1305 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1306 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1307 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1308
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1309 Auth_Store_Result Auth_Store_Update_Password(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1310 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1311 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1312 const char *new_encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1313 boolean revoke_other_sessions,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1314 const char *keep_token_digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1315 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1316 if (!p_store || !user_id || !new_encoded_hash)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1317 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1318 if (new_encoded_hash[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1319 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1320
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1321 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1322
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1323 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1324 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1325 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1326 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1327 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1328 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1329
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1330 const char *upd_params[] = {new_encoded_hash, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1331 int32 upd = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1332 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1333 "UPDATE users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1334 " SET password_hash = ?,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1335 " password_changed_at = strftime('%s','now'),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1336 " must_change_password = 0,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1337 " updated_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1338 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1339 2, upd_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1340 if (upd <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1341 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1342 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1343 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1344 return upd < 0 ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1345 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1346
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1347 if (revoke_other_sessions)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1348 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1349 int32 rev;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1350 if (keep_token_digest && keep_token_digest[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1351 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1352 const char *rev_params[] = {user_id, keep_token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1353 rev = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1354 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1355 "UPDATE auth_sessions"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1356 " SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1357 " WHERE user_id = ? AND token_digest != ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1358 2, rev_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1359 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1360 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1361 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1362 const char *rev_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1363 rev = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1364 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1365 "UPDATE auth_sessions"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1366 " SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1367 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1368 1, rev_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1369 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1370 if (rev < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1371 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1372 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1373 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1374 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1375 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1376 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1377
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1378 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1379 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1380 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1381 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1382 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1383 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1384
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1385 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1386 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1387 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1388
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1389 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1390 /* Session management */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1391 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1392
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1393 Auth_Store_Result Auth_Store_Create_Session(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1394 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1395 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1396 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1397 const char *csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1398 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1399 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1400 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1401 Auth_Session_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1402 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1403 if (!p_store || !user_id || !token_digest || !csrf_digest || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1404 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1405 if (!auth__session_arguments_are_valid(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1406 token_digest, csrf_digest, idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1407 absolute_ttl_secs, current_unix))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1408 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1409
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1410 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1411
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1412 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1413 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1414 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1415 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1416 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1417 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1418
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1419 /* Verify user is active and read password_changed_at snapshot. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1420 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1421 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1422 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1423 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1424 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1425 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1426 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1427 const char *sel_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1428 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1429 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1430 "SELECT status, password_changed_at FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1431 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1432 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1433 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1434 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1435 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1436 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1437 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1438 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1439 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1440 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1441 char cur_status[9];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1442 int64 pca;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1443 auth__copy_text_fixed(cur_status, sizeof(cur_status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1444 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1445 pca = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1446 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1447 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1448
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1449 if (strcmp(cur_status, "disabled") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1450 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1451 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1452 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1453 return AUTH_STORE_USER_DISABLED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1454 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1455
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1456 Auth_Store_Result insert_result = auth__insert_session_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1457 p_store, user_id, token_digest, csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1458 idle_ttl_secs, absolute_ttl_secs, current_unix, pca);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1459 if (insert_result != AUTH_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1460 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1461 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1462 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1463 return insert_result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1464 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1465
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1466 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1467 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1468 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1469 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1470 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1471 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1472
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1473 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1474
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1475 auth__fill_session_record(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1476 p_record, user_id, idle_ttl_secs, absolute_ttl_secs, current_unix, pca);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1477 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1478 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1479
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1480 Auth_Store_Result Auth_Store_Create_Session_CAS(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1481 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1482 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1483 const char *expected_password_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1484 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1485 const char *csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1486 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1487 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1488 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1489 Auth_Session_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1490 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1491 if (!p_store || !user_id || !expected_password_hash ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1492 expected_password_hash[0] == '\0' || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1493 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1494 if (!auth__session_arguments_are_valid(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1495 token_digest, csrf_digest, idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1496 absolute_ttl_secs, current_unix))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1497 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1498
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1499 char current_hash[AUTH_CRYPTO_PASSWORD_HASH_ENCODED_SIZE] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1500 char current_status[9] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1501 int64 password_changed_at = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1502 Auth_Store_Result result = AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1503
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1504 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1505 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1506 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1507 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1508 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1509 OPENSSL_cleanse(current_hash, sizeof(current_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1510 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1511 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1512
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1513 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1514 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1515 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1516 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1517 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1518 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1519
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1520 const char *select_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1521 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1522 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1523 "SELECT status, password_changed_at, password_hash"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1524 " FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1525 1, select_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1526 if (!p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1527 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1528 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1529 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1530 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1531 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1532 if (!Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1533 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1534 boolean query_error = Deita_Result_Set_Has_Error(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1535 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1536 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1537 result = auth__rollback(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1538 p_store, query_error ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1539 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1540 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1541
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1542 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1543 current_status, sizeof(current_status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1544 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1545 password_changed_at = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1546 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1547 current_hash, sizeof(current_hash),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1548 Deita_Result_Set_Get_Text(p_result, 2));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1549 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1550 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1551
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1552 if (strcmp(current_status, "disabled") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1553 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1554 result = auth__rollback(p_store, AUTH_STORE_USER_DISABLED);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1555 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1556 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1557 if (strcmp(current_hash, expected_password_hash) != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1558 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1559 result = auth__rollback(p_store, AUTH_STORE_STALE_PASSWORD);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1560 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1561 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1562
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1563 result = auth__insert_session_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1564 p_store, user_id, token_digest, csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1565 idle_ttl_secs, absolute_ttl_secs, current_unix, password_changed_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1566 if (result != AUTH_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1567 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1568 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1569 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1570 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1571
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1572 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1573 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1574 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1575 goto create_session_cas_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1576 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1577
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1578 auth__fill_session_record(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1579 p_record, user_id, idle_ttl_secs, absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1580 current_unix, password_changed_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1581 result = AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1582
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1583 create_session_cas_done:
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1584 OPENSSL_cleanse(current_hash, sizeof(current_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1585 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1586 return result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1587 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1588
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1589 Auth_Store_Result Auth_Store_Find_Session(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1590 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1591 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1592 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1593 Auth_Session_Record *p_session,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1594 Auth_User_Record *p_user)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1595 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1596 if (!p_store || !token_digest || !p_session || !p_user)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1597 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1598
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1599 memset(p_session, 0, sizeof(*p_session));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1600 memset(p_user, 0, sizeof(*p_user));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1601
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1602 Dowa_Arena *p_arena = Dowa_Arena_Create(4096);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1603 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1604 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1605
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1606 const char *params[] = {token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1607 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1608 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1609 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1610 "SELECT"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1611 " s.user_id, s.created_at, s.last_seen_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1612 " s.idle_expires_at, s.absolute_expires_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1613 " s.password_changed_at_snapshot, s.revoked_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1614 " u.id, u.username, u.normalized_username, u.role, u.status,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1615 " u.must_change_password, u.password_changed_at,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1616 " u.created_at, u.updated_at"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1617 " FROM auth_sessions s"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1618 " JOIN users u ON s.user_id = u.id"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1619 " WHERE s.token_digest = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1620 1, params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1621
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1622 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1623 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1624 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1625 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1626 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1627 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1628 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1629 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1630
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1631 /* Read session fields. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1632 auth__copy_text_fixed(p_session->user_id, sizeof(p_session->user_id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1633 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1634 p_session->created_at = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1635 p_session->last_seen_at = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1636 p_session->idle_expires_at = Deita_Result_Set_Get_Integer(p_result, 3);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1637 p_session->absolute_expires_at = Deita_Result_Set_Get_Integer(p_result, 4);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1638 p_session->password_changed_at_snapshot =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1639 Deita_Result_Set_Get_Integer(p_result, 5);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1640 boolean is_revoked =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1641 (Deita_Result_Set_Get_Column_Type(p_result, 6) != DEITA_COLUMN_TYPE_NULL);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1642
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1643 /* Read user fields (columns 7-15). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1644 /* Reuse auth__read_user_record after shifting: pass a pointer with offset */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1645 Auth_User_Record tmp_user;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1646 memset(&tmp_user, 0, sizeof(tmp_user));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1647 auth__copy_text_fixed(tmp_user.id, sizeof(tmp_user.id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1648 Deita_Result_Set_Get_Text(p_result, 7));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1649 auth__copy_text_fixed(tmp_user.username, sizeof(tmp_user.username),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1650 Deita_Result_Set_Get_Text(p_result, 8));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1651 auth__copy_text_fixed(tmp_user.normalized_username,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1652 sizeof(tmp_user.normalized_username),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1653 Deita_Result_Set_Get_Text(p_result, 9));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1654 auth__copy_text_fixed(tmp_user.role, sizeof(tmp_user.role),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1655 Deita_Result_Set_Get_Text(p_result, 10));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1656 auth__copy_text_fixed(tmp_user.status, sizeof(tmp_user.status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1657 Deita_Result_Set_Get_Text(p_result, 11));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1658 tmp_user.must_change_password = Deita_Result_Set_Get_Integer(p_result, 12) ?
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1659 TRUE : FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1660 tmp_user.password_changed_at = Deita_Result_Set_Get_Integer(p_result, 13);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1661 tmp_user.created_at = Deita_Result_Set_Get_Integer(p_result, 14);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1662 tmp_user.updated_at = Deita_Result_Set_Get_Integer(p_result, 15);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1663
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1664 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1665 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1666 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1667
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1668 /* Apply validity checks in order of specificity. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1669 if (is_revoked)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1670 return AUTH_STORE_REVOKED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1671
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1672 if (current_unix >= p_session->idle_expires_at ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1673 current_unix >= p_session->absolute_expires_at)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1674 return AUTH_STORE_EXPIRED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1675
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1676 if (strcmp(tmp_user.status, "disabled") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1677 return AUTH_STORE_USER_DISABLED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1678
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1679 if (tmp_user.password_changed_at != p_session->password_changed_at_snapshot)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1680 return AUTH_STORE_STALE_PASSWORD;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1681
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1682 *p_user = tmp_user;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1683 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1684 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1685
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1686 Auth_Store_Result Auth_Store_Touch_Session(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1687 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1688 const char *token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1689 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1690 int64 idle_ttl_secs)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1691 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1692 if (!p_store || !token_digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1693 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1694
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1695 char last_seen_str[32], idle_exp_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1696 snprintf(last_seen_str, sizeof(last_seen_str), "%lld", (long long)current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1697 snprintf(idle_exp_str, sizeof(idle_exp_str), "%lld",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1698 (long long)(current_unix + idle_ttl_secs));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1699
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1700 const char *params[] = {last_seen_str, idle_exp_str, token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1701
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1702 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1703 int32 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1704 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1705 "UPDATE auth_sessions"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1706 " SET last_seen_at = ?, idle_expires_at = ?"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1707 " WHERE token_digest = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1708 3, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1709 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1710
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1711 if (result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1712 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1713 return result == 0 ? AUTH_STORE_NOT_FOUND : AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1714 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1715
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1716 Auth_Store_Result Auth_Store_Revoke_Session(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1717 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1718 const char *token_digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1719 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1720 if (!p_store || !token_digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1721 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1722
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1723 const char *params[] = {token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1724
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1725 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1726 int32 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1727 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1728 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1729 " WHERE token_digest = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1730 1, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1731 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1732
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1733 if (result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1734 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1735 return result == 0 ? AUTH_STORE_NOT_FOUND : AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1736 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1737
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1738 Auth_Store_Result Auth_Store_Revoke_All_Sessions(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1739 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1740 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1741 const char *except_token_digest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1742 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1743 if (!p_store || !user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1744 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1745
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1746 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1747 int32 result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1748 if (except_token_digest && except_token_digest[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1749 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1750 const char *params[] = {user_id, except_token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1751 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1752 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1753 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1754 " WHERE user_id = ? AND token_digest != ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1755 2, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1756 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1757 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1758 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1759 const char *params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1760 result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1761 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1762 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1763 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1764 1, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1765 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1766 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1767
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1768 return result < 0 ? AUTH_STORE_ERROR : AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1769 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1770
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1771 Auth_Store_Result Auth_Store_Revoke_All_Sessions_Audited(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1772 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1773 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1774 const char *except_token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1775 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1776 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1777 if (!p_store || !user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1778 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1779 if (except_token_digest && except_token_digest[0] != '\0' &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1780 !auth__digest_is_valid(except_token_digest))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1781 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1782
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1783 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1784 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1785 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1786 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1787 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1788 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1789 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1790
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1791 Dowa_Arena *p_arena = Dowa_Arena_Create(1024);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1792 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1793 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1794 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1795 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1796 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1797 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1798
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1799 const char *find_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1800 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1801 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1802 "SELECT 1 FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1803 1, find_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1804 if (!p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1805 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1806 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1807 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1808 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1809 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1810 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1811 if (!Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1812 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1813 boolean query_error = Deita_Result_Set_Has_Error(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1814 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1815 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1816 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1817 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1818 return query_error ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1819 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1820 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1821 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1822
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1823 int32 revoke_result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1824 if (except_token_digest && except_token_digest[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1825 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1826 const char *params[] = {user_id, except_token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1827 revoke_result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1828 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1829 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1830 " WHERE user_id = ? AND token_digest != ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1831 2, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1832 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1833 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1834 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1835 const char *params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1836 revoke_result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1837 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1838 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1839 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1840 1, params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1841 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1842 if (revoke_result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1843 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1844 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1845 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1846 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1847 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1848
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1849 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1850 p_store, actor_user_id, "admin_sessions_revoked", user_id, NULL))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1851 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1852 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1853 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1854 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1855 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1856
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1857 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1858 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1859 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1860 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1861 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1862 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1863
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1864 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1865 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1866 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1867
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1868 Auth_Store_Result Auth_Store_Rotate_Session(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1869 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1870 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1871 const char *old_token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1872 const char *new_token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1873 const char *new_csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1874 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1875 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1876 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1877 Auth_Session_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1878 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1879 if (!p_store || !user_id || !old_token_digest || !new_token_digest ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1880 !new_csrf_digest || !p_record || !auth__digest_is_valid(old_token_digest))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1881 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1882 if (!auth__session_arguments_are_valid(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1883 new_token_digest, new_csrf_digest, idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1884 absolute_ttl_secs, current_unix))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1885 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1886
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1887 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1888
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1889 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1890 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1891 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1892 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1893 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1894 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1895
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1896 /* Verify user is active and read password_changed_at snapshot. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1897 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1898 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1899 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1900 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1901 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1902 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1903 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1904 const char *sel_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1905 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1906 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1907 "SELECT status, password_changed_at FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1908 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1909 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1910 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1911 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1912 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1913 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1914 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1915 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1916 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1917 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1918 char cur_status[9];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1919 int64 pca;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1920 auth__copy_text_fixed(cur_status, sizeof(cur_status),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1921 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1922 pca = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1923 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1924 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1925
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1926 if (strcmp(cur_status, "disabled") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1927 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1928 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1929 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1930 return AUTH_STORE_USER_DISABLED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1931 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1932
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1933 /* Insert new session. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1934 Auth_Store_Result insert_result = auth__insert_session_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1935 p_store, user_id, new_token_digest, new_csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1936 idle_ttl_secs, absolute_ttl_secs, current_unix, pca);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1937 if (insert_result != AUTH_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1938 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1939 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1940 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1941 return insert_result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1942 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1943
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1944 /* Revoke old session (idempotent: ignore if already revoked). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1945 const char *rev_params[] = {old_token_digest};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1946 int32 revoke_result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1947 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1948 "UPDATE auth_sessions SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1949 " WHERE token_digest = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1950 1, rev_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1951 if (revoke_result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1952 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1953 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1954 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1955 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1956 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1957
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1958 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1959 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1960 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1961 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1962 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1963 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1964
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1965 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1966
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1967 auth__fill_session_record(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1968 p_record, user_id, idle_ttl_secs, absolute_ttl_secs, current_unix, pca);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1969 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1970 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1971
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1972 Auth_Store_Result Auth_Store_Self_Change_Password(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1973 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1974 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1975 const char *old_encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1976 const char *new_encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1977 const char *new_token_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1978 const char *new_csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1979 int64 idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1980 int64 absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1981 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1982 Auth_Session_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1983 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1984 if (!p_store || !user_id || !old_encoded_hash || !new_encoded_hash ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1985 old_encoded_hash[0] == '\0' || new_encoded_hash[0] == '\0' || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1986 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1987 if (!auth__session_arguments_are_valid(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1988 new_token_digest, new_csrf_digest, idle_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1989 absolute_ttl_secs, current_unix))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1990 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1991
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1992 char current_hash[AUTH_CRYPTO_PASSWORD_HASH_ENCODED_SIZE] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1993 char reread_hash[AUTH_CRYPTO_PASSWORD_HASH_ENCODED_SIZE] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1994 char status[9] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1995 char timestamp[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1996 snprintf(timestamp, sizeof(timestamp), "%lld", (long long)current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1997 Auth_Store_Result result = AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1998
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1999 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2000 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2001 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2002 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2003 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2004 OPENSSL_cleanse(current_hash, sizeof(current_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2005 OPENSSL_cleanse(reread_hash, sizeof(reread_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2006 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2007 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2008
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2009 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2010 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2011 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2012 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2013 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2014 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2015
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2016 const char *select_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2017 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2018 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2019 "SELECT status, password_hash FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2020 1, select_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2021 if (!p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2022 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2023 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2024 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2025 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2026 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2027 if (!Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2028 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2029 boolean query_error = Deita_Result_Set_Has_Error(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2030 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2031 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2032 result = auth__rollback(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2033 p_store, query_error ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2034 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2035 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2036 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2037 status, sizeof(status), Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2038 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2039 current_hash, sizeof(current_hash),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2040 Deita_Result_Set_Get_Text(p_result, 1));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2041 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2042 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2043
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2044 if (strcmp(status, "disabled") == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2045 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2046 result = auth__rollback(p_store, AUTH_STORE_USER_DISABLED);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2047 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2048 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2049 if (strcmp(current_hash, old_encoded_hash) != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2050 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2051 result = auth__rollback(p_store, AUTH_STORE_STALE_PASSWORD);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2052 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2053 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2054
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2055 const char *update_params[] = {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2056 new_encoded_hash, timestamp, timestamp, user_id, old_encoded_hash
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2057 };
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2058 int32 update_result = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2059 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2060 "UPDATE users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2061 " SET password_hash = ?, password_changed_at = ?,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2062 " must_change_password = 0, updated_at = ?"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2063 " WHERE id = ? AND password_hash = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2064 5, update_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2065 if (update_result < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2066 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2067 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2068 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2069 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2070 if (update_result == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2071 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2072 result = auth__rollback(p_store, AUTH_STORE_STALE_PASSWORD);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2073 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2074 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2075
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2076 p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2077 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2078 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2079 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2080 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2081 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2082 p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2083 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2084 "SELECT status, password_changed_at, password_hash"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2085 " FROM users WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2086 1, select_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2087 if (!p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2088 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2089 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2090 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2091 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2092 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2093 if (!Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2094 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2095 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2096 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2097 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2098 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2099 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2100 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2101 status, sizeof(status), Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2102 int64 password_changed_at = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2103 auth__copy_text_fixed(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2104 reread_hash, sizeof(reread_hash),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2105 Deita_Result_Set_Get_Text(p_result, 2));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2106 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2107 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2108 if (strcmp(status, "active") != 0 ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2109 password_changed_at != current_unix ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2110 strcmp(reread_hash, new_encoded_hash) != 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2111 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2112 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2113 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2114 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2115
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2116 const char *revoke_params[] = {timestamp, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2117 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2118 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2119 "UPDATE auth_sessions SET revoked_at = ?"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2120 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2121 2, revoke_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2122 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2123 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2124 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2125 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2126
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2127 result = auth__insert_session_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2128 p_store, user_id, new_token_digest, new_csrf_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2129 idle_ttl_secs, absolute_ttl_secs, current_unix, password_changed_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2130 if (result != AUTH_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2131 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2132 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2133 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2134 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2135
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2136 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2137 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2138 result = auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2139 goto self_change_done;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2140 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2141
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2142 auth__fill_session_record(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2143 p_record, user_id, idle_ttl_secs, absolute_ttl_secs,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2144 current_unix, password_changed_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2145 result = AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2146
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2147 self_change_done:
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2148 OPENSSL_cleanse(current_hash, sizeof(current_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2149 OPENSSL_cleanse(reread_hash, sizeof(reread_hash));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2150 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2151 return result;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2152 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2153
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2154 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2155 /* Guest identity */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2156 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2157
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2158 Auth_Store_Result Auth_Store_Upsert_Guest_Identity(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2159 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2160 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2161 const char *ip_binding_digest,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2162 int64 expires_at,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2163 Auth_Guest_Identity_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2164 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2165 if (!p_store || !guest_id || !ip_binding_digest || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2166 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2167
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2168 char exp_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2169 snprintf(exp_str, sizeof(exp_str), "%lld", (long long)expires_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2170
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2171 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2172
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2173 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2174 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2175 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2176 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2177 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2178 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2179
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2180 /* INSERT OR IGNORE so usage data is not cascade-deleted on upsert. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2181 const char *ins_params[] = {guest_id, ip_binding_digest, exp_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2182 Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2183 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2184 "INSERT OR IGNORE INTO guest_identities (id, ip_binding_digest, expires_at)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2185 " VALUES (?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2186 3, ins_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2187
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2188 /* Always refresh last_seen_at and expires_at. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2189 const char *upd_params[] = {exp_str, guest_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2190 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2191 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2192 "UPDATE guest_identities"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2193 " SET last_seen_at = strftime('%s','now'), expires_at = ?"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2194 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2195 2, upd_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2196 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2197 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2198 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2199 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2200 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2201
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2202 /* Read back the current row. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2203 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2204 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2205 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2206 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2207 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2208 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2209 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2210 const char *sel_params[] = {guest_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2211 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2212 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2213 "SELECT id, created_at, last_seen_at, expires_at"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2214 " FROM guest_identities WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2215 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2216 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2217 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2218 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2219 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2220 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2221 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2222 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2223 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2224 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2225 auth__copy_text_fixed(p_record->id, sizeof(p_record->id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2226 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2227 p_record->created_at = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2228 p_record->last_seen_at = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2229 p_record->expires_at = Deita_Result_Set_Get_Integer(p_result, 3);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2230 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2231 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2232
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2233 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2234 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2235 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2236 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2237 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2238 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2239
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2240 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2241 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2242 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2243
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2244 Auth_Store_Result Auth_Store_Find_Guest_Identity(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2245 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2246 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2247 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2248 Auth_Guest_Identity_Record *p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2249 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2250 if (!p_store || !guest_id || !p_record)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2251 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2252
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2253 memset(p_record, 0, sizeof(*p_record));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2254
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2255 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2256 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2257 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2258
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2259 const char *params[] = {guest_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2260 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2261 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2262 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2263 "SELECT id, created_at, last_seen_at, expires_at"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2264 " FROM guest_identities WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2265 1, params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2266 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2267 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2268 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2269 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2270 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2271 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2272 return AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2273 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2274 auth__copy_text_fixed(p_record->id, sizeof(p_record->id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2275 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2276 p_record->created_at = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2277 p_record->last_seen_at = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2278 p_record->expires_at = Deita_Result_Set_Get_Integer(p_result, 3);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2279 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2280 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2281 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2282
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2283 if (current_unix >= p_record->expires_at)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2284 return AUTH_STORE_EXPIRED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2285
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2286 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2287 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2288
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2289 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2290 /* Guest quota */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2291 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2292
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2293 static void auth__i64_str(char *buf, size_t size, int64 value)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2294 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2295 snprintf(buf, size, "%lld", (long long)value);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2296 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2297
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2298 Auth_Store_Result Auth_Store_Guest_Get_Usage(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2299 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2300 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2301 int64 window_start,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2302 Auth_Store_Guest_Usage *p_usage)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2303 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2304 if (!p_store || !guest_id || !p_usage)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2305 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2306
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2307 memset(p_usage, 0, sizeof(*p_usage));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2308
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2309 char ws_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2310 auth__i64_str(ws_str, sizeof(ws_str), window_start);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2311
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2312 Dowa_Arena *p_arena = Dowa_Arena_Create(2048);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2313 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2314 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2315
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2316 const char *params[] = {guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2317 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2318 auth__reap_expired_reservations_locked(p_store, (int64)time(NULL));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2319 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2320 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2321 "SELECT turns_used, output_tokens_used, output_tokens_reserved"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2322 " FROM guest_usage WHERE guest_id = ? AND window_start = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2323 2, params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2324 if (p_result && Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2325 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2326 p_usage->turns_used = Deita_Result_Set_Get_Integer(p_result, 0);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2327 p_usage->output_tokens_used = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2328 p_usage->output_tokens_reserved = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2329 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2330 if (p_result)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2331 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2332 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2333 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2334 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2335 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2336
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2337 Auth_Store_Guest_Quota_Result Auth_Store_Guest_Reserve(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2338 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2339 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2340 const char *request_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2341 int64 window_start,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2342 int64 max_output_tokens,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2343 int64 turns_limit,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2344 int64 tokens_limit,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2345 int64 reservation_expires)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2346 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2347 if (!p_store || !guest_id || !request_id ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2348 max_output_tokens <= 0 || turns_limit <= 0 || tokens_limit <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2349 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2350
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2351 char ws_str[32], exp_str[32], tok_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2352 auth__i64_str(ws_str, sizeof(ws_str), window_start);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2353 auth__i64_str(exp_str, sizeof(exp_str), reservation_expires);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2354 auth__i64_str(tok_str, sizeof(tok_str), max_output_tokens);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2355
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2356 Dowa_Arena *p_arena = Dowa_Arena_Create(4096);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2357 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2358 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2359
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2360 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2361
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2362 if (Deita_Query_Execute_Update(p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2363 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2364 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2365 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2366 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2367 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2368 auth__reap_expired_reservations_locked(p_store, (int64)time(NULL));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2369
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2370 /* Ensure usage row exists for this window. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2371 const char *ins_params[] = {guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2372 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2373 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2374 "INSERT OR IGNORE INTO guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2375 " (guest_id, window_start, count)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2376 " VALUES (?, ?, 0)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2377 2, ins_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2378 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2379 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2380 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2381 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2382 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2383 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2384
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2385 /* Read current usage. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2386 const char *sel_params[] = {guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2387 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2388 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2389 "SELECT turns_used, output_tokens_used, output_tokens_reserved"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2390 " FROM guest_usage WHERE guest_id = ? AND window_start = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2391 2, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2392 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2393 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2394 if (p_result) Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2395 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2396 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2397 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2398 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2399 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2400 int64 turns_used = Deita_Result_Set_Get_Integer(p_result, 0);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2401 int64 tokens_used = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2402 int64 tokens_resvd = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2403 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2404
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2405 /* Check turn limit. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2406 if (turns_used >= turns_limit)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2407 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2408 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2409 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2410 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2411 return AUTH_STORE_GUEST_QUOTA_TURNS_EXHAUSTED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2412 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2413
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2414 /* Check token limit: used + reserved + new_reservation <= limit. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2415 if (tokens_used + tokens_resvd + max_output_tokens > tokens_limit)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2416 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2417 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2418 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2419 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2420 return AUTH_STORE_GUEST_QUOTA_TOKENS_EXHAUSTED;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2421 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2422
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2423 /* Update usage: charge turn, add token reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2424 const char *upd_params[] = {tok_str, guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2425 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2426 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2427 "UPDATE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2428 " SET turns_used = turns_used + 1,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2429 " output_tokens_reserved = output_tokens_reserved + ?,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2430 " count = count + 1"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2431 " WHERE guest_id = ? AND window_start = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2432 3, upd_params) <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2433 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2434 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2435 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2436 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2437 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2438 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2439
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2440 /* Insert reservation row. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2441 const char *res_params[] = {request_id, guest_id, ws_str, tok_str, exp_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2442 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2443 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2444 "INSERT INTO guest_usage_reservations"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2445 " (request_id, guest_id, window_start, output_tokens_reserved, expires_at)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2446 " VALUES (?, ?, ?, ?, ?)",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2447 5, res_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2448 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2449 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2450 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2451 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2452 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2453 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2454
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2455 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2456 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2457 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2458 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2459 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2460 return AUTH_STORE_GUEST_QUOTA_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2461 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2462
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2463 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2464 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2465 return AUTH_STORE_GUEST_QUOTA_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2466 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2467
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2468 Auth_Store_Result Auth_Store_Guest_Reconcile(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2469 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2470 const char *request_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2471 int64 actual_output_tokens)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2472 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2473 if (!p_store || !request_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2474 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2475 if (actual_output_tokens < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2476 actual_output_tokens = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2477
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2478 Dowa_Arena *p_arena = Dowa_Arena_Create(4096);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2479 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2480 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2481
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2482 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2483
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2484 if (Deita_Query_Execute_Update(p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2485 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2486 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2487 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2488 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2489 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2490
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2491 /* Fetch reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2492 const char *sel_params[] = {request_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2493 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2494 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2495 "SELECT guest_id, window_start, output_tokens_reserved"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2496 " FROM guest_usage_reservations WHERE request_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2497 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2498 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2499 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2500 /* Idempotent: reservation already gone. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2501 if (p_result) Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2502 Deita_Query_Execute_Update(p_store->p_connection, "COMMIT");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2503 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2504 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2505 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2506 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2507
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2508 char guest_id[37];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2509 auth__copy_text_fixed(guest_id, sizeof(guest_id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2510 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2511 int64 window_start = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2512 int64 tokens_reserved = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2513 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2514
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2515 /* Charge provider-reported usage even when it exceeds the reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2516 int64 to_charge = actual_output_tokens;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2517
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2518 char ws_str[32], charge_str[32], res_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2519 auth__i64_str(ws_str, sizeof(ws_str), window_start);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2520 auth__i64_str(charge_str, sizeof(charge_str), to_charge);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2521 auth__i64_str(res_str, sizeof(res_str), tokens_reserved);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2522
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2523 /* Update usage: add actual tokens, subtract reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2524 const char *upd_params[] = {charge_str, res_str, guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2525 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2526 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2527 "UPDATE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2528 " SET output_tokens_used = output_tokens_used + ?,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2529 " output_tokens_reserved = MAX(0, output_tokens_reserved - ?)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2530 " WHERE guest_id = ? AND window_start = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2531 4, upd_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2532 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2533 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2534 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2535 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2536 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2537 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2538
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2539 /* Delete reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2540 const char *del_params[] = {request_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2541 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2542 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2543 "DELETE FROM guest_usage_reservations WHERE request_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2544 1, del_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2545 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2546 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2547 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2548 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2549 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2550 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2551
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2552 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2553 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2554 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2555 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2556 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2557 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2558 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2559
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2560 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2561 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2562 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2563 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2564
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2565 Auth_Store_Result Auth_Store_Guest_Release(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2566 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2567 const char *request_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2568 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2569 if (!p_store || !request_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2570 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2571
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2572 Dowa_Arena *p_arena = Dowa_Arena_Create(4096);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2573 if (!p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2574 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2575
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2576 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2577
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2578 if (Deita_Query_Execute_Update(p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2579 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2580 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2581 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2582 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2583 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2584
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2585 /* Fetch reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2586 const char *sel_params[] = {request_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2587 Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2588 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2589 "SELECT guest_id, window_start, output_tokens_reserved"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2590 " FROM guest_usage_reservations WHERE request_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2591 1, sel_params, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2592 if (!p_result || !Deita_Result_Set_Next(p_result))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2593 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2594 /* Idempotent: reservation already gone. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2595 if (p_result) Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2596 Deita_Query_Execute_Update(p_store->p_connection, "COMMIT");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2597 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2598 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2599 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2600 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2601
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2602 char guest_id[37];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2603 auth__copy_text_fixed(guest_id, sizeof(guest_id),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2604 Deita_Result_Set_Get_Text(p_result, 0));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2605 int64 window_start = Deita_Result_Set_Get_Integer(p_result, 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2606 int64 tokens_reserved = Deita_Result_Set_Get_Integer(p_result, 2);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2607 Deita_Result_Set_Free(p_result);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2608
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2609 char ws_str[32], res_str[32];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2610 auth__i64_str(ws_str, sizeof(ws_str), window_start);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2611 auth__i64_str(res_str, sizeof(res_str), tokens_reserved);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2612
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2613 /* Release token reservation; turns_used is unchanged (turn already charged). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2614 const char *upd_params[] = {res_str, guest_id, ws_str};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2615 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2616 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2617 "UPDATE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2618 " SET output_tokens_reserved = MAX(0, output_tokens_reserved - ?)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2619 " WHERE guest_id = ? AND window_start = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2620 3, upd_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2621 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2622 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2623 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2624 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2625 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2626 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2627
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2628 /* Delete reservation. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2629 const char *del_params[] = {request_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2630 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2631 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2632 "DELETE FROM guest_usage_reservations WHERE request_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2633 1, del_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2634 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2635 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2636 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2637 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2638 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2639 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2640
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2641 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2642 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2643 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2644 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2645 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2646 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2647 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2648
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2649 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2650 Dowa_Arena_Free(p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2651 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2652 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2653
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2654 Auth_Store_Result Auth_Store_Guest_Clear_Reservations(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2655 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2656 const char *guest_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2657 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2658 if (!p_store || !guest_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2659 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2660
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2661 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2662
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2663 if (Deita_Query_Execute_Update(p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2664 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2665 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2666 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2667 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2668
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2669 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2670 * Subtract each window's reserved tokens from the usage row.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2671 * The correlated subquery aggregates reservations per window.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2672 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2673 const char *upd_params[] = {guest_id, guest_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2674 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2675 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2676 "UPDATE guest_usage"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2677 " SET output_tokens_reserved = MAX(0, output_tokens_reserved - ("
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2678 " SELECT COALESCE(SUM(r.output_tokens_reserved), 0)"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2679 " FROM guest_usage_reservations r"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2680 " WHERE r.guest_id = ? AND r.window_start = guest_usage.window_start"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2681 " ))"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2682 " WHERE guest_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2683 2, upd_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2684 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2685 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2686 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2687 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2688 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2689
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2690 /* Delete all reservations for this guest. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2691 const char *del_params[] = {guest_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2692 if (Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2693 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2694 "DELETE FROM guest_usage_reservations WHERE guest_id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2695 1, del_params) < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2696 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2697 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2698 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2699 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2700 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2701
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2702 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2703 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2704 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2705 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2706 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2707 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2708
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2709 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2710 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2711 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2712
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2713 Auth_Store_Result Auth_Store_Guest_Reap_Expired(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2714 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2715 int64 current_unix)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2716 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2717 if (!p_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2718 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2719 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2720 auth__reap_expired_reservations_locked(p_store, current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2721 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2722 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2723 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2724
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2725 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2726 /* Audit log (public) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2727 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2728
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2729 Auth_Store_Result Auth_Store_Insert_Audit_Log(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2730 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2731 const char *actor_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2732 const char *action,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2733 const char *target_user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2734 const char *detail)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2735 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2736 if (!p_store || !action || action[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2737 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2738
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2739 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2740 boolean inserted = auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2741 p_store, actor_user_id, action, target_user_id, detail);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2742 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2743 return inserted ? AUTH_STORE_OK : AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2744 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2745
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2746 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2747 /* Admin password reset */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2748 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2749
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2750 Auth_Store_Result Auth_Store_Admin_Reset_Password(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2751 Auth_Store *p_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2752 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2753 const char *new_encoded_hash,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2754 const char *actor_user_id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2755 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2756 if (!p_store || !user_id || !new_encoded_hash)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2757 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2758 if (new_encoded_hash[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2759 return AUTH_STORE_INVALID_ARG;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2760
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2761 pthread_mutex_lock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2762
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2763 if (Deita_Query_Execute_Update(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2764 p_store->p_connection, "BEGIN IMMEDIATE") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2765 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2766 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2767 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2768 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2769
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2770 const char *upd_params[] = {new_encoded_hash, user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2771 int32 upd = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2772 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2773 "UPDATE users"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2774 " SET password_hash = ?,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2775 " password_changed_at = strftime('%s','now'),"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2776 " must_change_password = 1,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2777 " updated_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2778 " WHERE id = ?",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2779 2, upd_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2780 if (upd <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2781 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2782 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2783 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2784 return upd < 0 ? AUTH_STORE_ERROR : AUTH_STORE_NOT_FOUND;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2785 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2786
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2787 const char *rev_params[] = {user_id};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2788 int32 rev = Deita_Query_Execute_Update_Prepared(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2789 p_store->p_connection,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2790 "UPDATE auth_sessions"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2791 " SET revoked_at = strftime('%s','now')"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2792 " WHERE user_id = ? AND revoked_at IS NULL",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2793 1, rev_params);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2794 if (rev < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2795 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2796 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2797 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2798 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2799 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2800
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2801 if (!auth__insert_audit_log_locked(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2802 p_store, actor_user_id, "admin_temp_password_reset", user_id, NULL))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2803 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2804 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2805 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2806 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2807 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2808
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2809 if (Deita_Query_Execute_Update(p_store->p_connection, "COMMIT") < 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2810 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2811 auth__rollback(p_store, AUTH_STORE_ERROR);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2812 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2813 return AUTH_STORE_ERROR;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2814 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2815
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2816 pthread_mutex_unlock(&p_store->mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2817 return AUTH_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2818 }