1use crate::formats::base64::{
5 bytes_to_standard_base64, standard_base64_to_bytes,
6};
7use crate::utilities::call_ipc_sync;
8use crate::utilities::json::jq;
9use crate::workspace::ipc_old::resolve_workspace_channel;
10use crate::{bail_if_none, debug_fmt, error, json_value, log, warn};
11use anyhow::Result;
12
13fn ipc_get<T: std::str::FromStr>(
15 method: &str,
16 args: serde_json::Value,
17 jq_path: &str,
18) -> Option<T> {
19 let channel = resolve_workspace_channel();
20 if channel.is_err() {
21 return None;
22 }
23 let channel = channel.unwrap();
24 let ipc_result = call_ipc_sync(&channel, method, args);
25 let ipc_result = match ipc_result {
26 Ok(r) => r,
27 Err(_) => return None,
28 };
29
30 let ipc_result = ipc_result.as_str();
31
32 let parsed: serde_json::Value = serde_json::from_str(ipc_result).ok()?;
34 let value = parsed.get("value");
35 let none = parsed.get("none");
36 if value.is_none() && none.is_none() {
37 warn!("ipc_put_delete: {} returned neither value nor none", method);
38 return None;
39 }
40 if none.is_some() {
41 return None;
42 }
43
44 let value = jq(jq_path, ipc_result).ok()?;
45 let s = value.as_str();
46 T::from_str(s).ok()
47}
48
49fn ipc_put_delete(method: &str, args: serde_json::Value) -> Result<()> {
51 let channel = resolve_workspace_channel()?;
52 let ipc_result = call_ipc_sync(&channel, method, args)?;
53 let parsed: serde_json::Value = serde_json::from_str(ipc_result.as_str())
54 .ok()
55 .ok_or(anyhow::anyhow!("Failed to parse IPC response"))?;
56 let value = parsed.get("value");
57 let error = parsed.get("error");
58 if value.is_none() && error.is_none() {
59 warn!(
60 "ipc_put_delete: {} returned neither value nor error",
61 method
62 );
63 return Err(anyhow::anyhow!("IPC response missing value; {method}"));
64 }
65 if error.is_some() {
66 let error_msg = error
67 .and_then(|e| e.as_str())
68 .unwrap_or("Unknown error")
69 .to_string();
70 error!("ipc_put_delete: {} returned error: {}", method, &error_msg);
71 return Err(anyhow::anyhow!("IPC error from {method}: {error_msg}"));
72 }
73 Ok(())
74}
75
76fn ipc_get_vec_u64(method: &str, args: serde_json::Value) -> Result<Vec<u64>> {
78 let channel = resolve_workspace_channel()?;
79 let ipc_result = call_ipc_sync(&channel, method, args);
80 let ipc_result = match ipc_result {
81 Ok(r) => r,
82 Err(e) => return Err(anyhow::anyhow!("Failed to call IPC sync: {e}")),
83 };
84 debug_fmt!("ipc_get_vec_u64: {} -> {}", method, ipc_result);
85 let parsed: serde_json::Value = serde_json::from_str(ipc_result.as_str())?;
86 let value = parsed.get("value");
87 let error = parsed.get("error");
88 if value.is_none() && error.is_none() {
89 warn!(
90 "ipc_get_vec_u64: {} returned neither value nor error: {:?}",
91 method, ipc_result
92 );
93 return Err(anyhow::anyhow!("IPC response missing value; {method}"));
94 }
95 if error.is_some() {
96 return Err(anyhow::anyhow!("IPC error from {method}: {ipc_result}"));
97 }
98 let value = bail_if_none!(value);
99 let arr = bail_if_none!(value.as_array());
100 let mut result = Vec::new();
101 for v in arr {
102 if let Some(n) = v.as_u64() {
103 result.push(n);
104 } else {
105 error!("ipc_get_vec_u64: {} returned non-u64 value", method);
106 return Err(anyhow::anyhow!(
107 "IPC response contained non-u64 value; {method}"
108 ));
109 }
110 }
111 Ok(result)
112}
113
114pub fn get_str_u64(db: &str, key: &str) -> Option<u64> {
116 ipc_get::<u64>(
117 "get_str_u64",
118 json_value!({ "db".to_string() => db, "key".to_string() => key }),
119 ".value",
120 )
121}
122
123pub fn get_all_u64_keys(db: &str) -> Result<Vec<u64>> {
124 ipc_get_vec_u64(
125 "get_all_u64_keys",
126 json_value!({ "db".to_string() => db }),
127 )
128}
129
130pub fn put_str_u64(db: &str, key: &str, value: u64) -> Result<()> {
132 ipc_put_delete(
133 "put_str_u64",
134 json_value!({ "db".to_string() => db, "key".to_string() => key, "value".to_string() => value }),
135 )
136}
137
138pub fn delete_str_u64(db: &str, key: &str) -> Result<()> {
140 ipc_put_delete(
141 "delete_str_u64",
142 json_value!({ "db".to_string() => db, "key".to_string() => key }),
143 )
144}
145
146pub fn get_u64_str(db: &str, key: u64) -> Option<String> {
148 ipc_get::<String>(
149 "get_u64_str",
150 json_value!({ "db".to_string() => db, "key".to_string() => key }),
151 ".value",
152 )
153}
154
155pub fn put_u64_str(db: &str, key: u64, value: &str) -> Result<()> {
157 ipc_put_delete(
158 "put_u64_str",
159 json_value!({ "db".to_string() => db, "key".to_string() => key, "value".to_string() => value }),
160 )
161}
162
163pub fn delete_u64_str(db: &str, key: u64) -> Result<()> {
165 ipc_put_delete(
166 "delete_u64_str",
167 json_value!({ "db".to_string() => db, "key".to_string() => key }),
168 )
169}
170
171pub fn get_u64_bytes(db: &str, key: u64) -> Option<Vec<u8>> {
173 let channel = resolve_workspace_channel();
174 if channel.is_err() {
175 return None;
176 }
177 let channel = channel.ok()?;
178 let ipc_result = call_ipc_sync(
179 &channel,
180 "get_u64_bytes",
181 json_value!({ "db".to_string() => db, "key".to_string() => key }),
182 );
183 let ipc_result = match ipc_result {
184 Ok(r) => r,
185 Err(_) => return None,
186 };
187 let parsed: serde_json::Value =
188 serde_json::from_str(ipc_result.as_str()).ok()?;
189 let value = parsed.get("value")?.as_str()?;
190 let r = standard_base64_to_bytes(value.to_string()).ok();
194 log!(format!(
195 "ipc_get: get_u64_bytes {} {} -> {} bytes",
196 db,
197 key,
198 String::from_utf8_lossy(r.clone()?.as_slice()),
199 ));
200 r
201}
202
203pub fn put_u64_bytes(db: &str, key: u64, value: &[u8]) -> Result<()> {
205 return ipc_put_delete(
206 "put_u64_bytes",
207 json_value!({ "db".to_string() => db, "key".to_string() => key, "value".to_string() => value }),
208 );
209 let encoded = bytes_to_standard_base64(value);
210 ipc_put_delete(
211 "put_u64_bytes",
212 json_value!({ "db".to_string() => db, "key".to_string() => key, "value".to_string() => encoded }),
213 )
214}
215
216pub fn delete_u64_bytes(db: &str, key: u64) -> Result<()> {
218 ipc_put_delete(
219 "delete_u64_bytes",
220 json_value!({ "db".to_string() => db, "key".to_string() => key }),
221 )
222}
223
224pub fn get_user_id(name: &str) -> Option<u64> {
226 get_str_u64("users/ids", name)
227}
228
229pub fn get_all_user_ids() -> Result<Vec<u64>> {
230 get_all_u64_keys("users/ids_rev")
231}
232
233pub fn get_user_name(user_id: u64) -> Option<String> {
234 get_u64_str("users/ids_rev", user_id)
235}
236
237pub fn put_user_id(name: &str, user_id: u64) -> Result<()> {
238 put_str_u64("users/ids", name, user_id)?;
239 put_u64_str("users/ids_rev", user_id, name)
240}
241
242pub fn delete_user_id(name: &str, user_id: u64) -> Result<()> {
243 delete_str_u64("users/ids", name)?;
244 delete_u64_str("users/ids_rev", user_id)
245}
246
247pub fn get_user_uuid(id: u64) -> Option<Vec<u8>> {
249 get_u64_bytes("users/uuids", id)
250}
251
252pub fn put_user_uuid(id: u64, uuid: &[u8]) -> Result<()> {
253 put_u64_bytes("users/uuids", id, uuid)
254}
255
256pub fn delete_user_uuid(id: u64) -> Result<()> {
257 delete_u64_bytes("users/uuids", id)
258}
259
260pub fn get_user_auth(user_id: u64) -> Option<String> {
262 get_u64_str("users/auth", user_id)
263}
264
265pub fn put_user_auth(user_id: u64, phc_hash: &str) -> Result<()> {
266 put_u64_str("users/auth", user_id, phc_hash)
267}
268
269pub fn delete_user_auth(user_id: u64) -> Result<()> {
270 delete_u64_str("users/auth", user_id)
271}
272
273pub fn get_user_display_name(user_id: u64) -> Option<Vec<u8>> {
275 get_u64_bytes("users/display_names", user_id)
276}
277
278pub fn put_user_display_name(user_id: u64, display_name: &[u8]) -> Result<()> {
279 put_u64_bytes("users/display_names", user_id, display_name)
280}
281
282pub fn delete_user_display_name(user_id: u64) -> Result<()> {
283 delete_u64_bytes("users/display_names", user_id)
284}
285pub fn get_user_pictures(user_id: u64) -> Option<Vec<u8>> {
287 get_u64_bytes("users/pictures", user_id)
288}
289
290pub fn put_user_picture(user_id: u64, picture_data: &[u8]) -> Result<()> {
291 put_u64_bytes("users/pictures", user_id, picture_data)
292}
293
294pub fn delete_user_picture(user_id: u64) -> Result<()> {
295 delete_u64_bytes("users/pictures", user_id)
296}
297
298pub fn get_user_kek_params(user_id: u64) -> Option<Vec<u8>> {
300 get_u64_bytes("users/key_encryption_key_params", user_id)
301}
302
303pub fn put_user_kek_params(user_id: u64, kek_params: &[u8]) -> Result<()> {
304 put_u64_bytes("users/key_encryption_key_params", user_id, kek_params)
305}
306
307pub fn delete_user_kek_params(user_id: u64) -> Result<()> {
308 delete_u64_bytes("users/key_encryption_key_params", user_id)
309}
310
311pub fn get_user_wrapped_dek(user_id: u64) -> Option<Vec<u8>> {
313 get_u64_bytes("users/wrapped_dek", user_id)
314}
315
316pub fn put_user_wrapped_dek(user_id: u64, wrapped_dek: &[u8]) -> Result<()> {
317 put_u64_bytes("users/wrapped_dek", user_id, wrapped_dek)
318}
319
320pub fn delete_user_wrapped_dek(user_id: u64) -> Result<()> {
321 delete_u64_bytes("users/wrapped_dek", user_id)
322}
323
324pub fn get_user_pubkey(user_id: u64) -> Option<Vec<u8>> {
326 get_u64_bytes("users/pubkeys", user_id)
327}
328
329pub fn put_user_pubkey(user_id: u64, pubkey: &[u8]) -> Result<()> {
330 put_u64_bytes("users/pubkeys", user_id, pubkey)
331}
332
333pub fn delete_user_pubkey(user_id: u64) -> Result<()> {
334 delete_u64_bytes("users/pubkeys", user_id)
335}