Skip to main content

tuwunel_api/client/backup/
mod.rs

1mod keys;
2mod keys_room;
3mod keys_session;
4mod version;
5mod version_id;
6
7use ruma::{CanonicalJsonValue, UInt, UserId, serde::Raw};
8use serde::Deserialize;
9use tuwunel_core::{Error, Result};
10use tuwunel_service::Services;
11
12pub(crate) use self::{
13	keys::{add_backup_keys_route, delete_backup_keys_route, get_backup_keys_route},
14	keys_room::{
15		add_backup_keys_for_room_route, delete_backup_keys_for_room_route,
16		get_backup_keys_for_room_route,
17	},
18	keys_session::{
19		add_backup_keys_for_session_route, delete_backup_keys_for_session_route,
20		get_backup_keys_for_session_route,
21	},
22	version::{create_backup_version_route, get_latest_backup_info_route},
23	version_id::{
24		delete_backup_version_route, get_backup_info_route, update_backup_version_route,
25	},
26};
27
28/// Overrides ruma's internal `AlgorithmWithData` shape required by the GET
29/// `/room_keys/version[/{version}]` response serializer. Validating against
30/// this will not raise a serialization error (HTTP 500) when responding.
31#[derive(Deserialize)]
32#[expect(unused)]
33struct AlgorithmShape {
34	algorithm: Raw<CanonicalJsonValue>,
35	auth_data: Raw<CanonicalJsonValue>,
36}
37
38pub(super) fn validate_algorithm_shape<T>(raw: &Raw<T>) -> Result {
39	raw.deserialize_as_unchecked::<AlgorithmShape>()
40		.map_err(Into::into)
41		.map(drop)
42}
43
44pub(super) async fn get_count_etag(
45	services: &Services,
46	sender_user: &UserId,
47	version: &str,
48) -> Result<(UInt, String)> {
49	let metadata = services
50		.key_backups
51		.get_count_etag(sender_user, version)
52		.await?;
53
54	format_count_etag(metadata)
55}
56
57pub(super) fn format_count_etag((count, etag): (usize, u64)) -> Result<(UInt, String)> {
58	let count = count.try_into().map_err(Error::from)?;
59
60	Ok((count, etag.to_string()))
61}