Skip to main content

tuwunel_api/client/backup/
keys.rs

1use axum::extract::State;
2use ruma::api::client::backup::{
3	add_backup_keys::{self, v3::Response as AddResponse},
4	delete_backup_keys::{self, v3::Response as DeleteResponse},
5	get_backup_keys::{self, v3::Response as GetResponse},
6};
7use tuwunel_core::{Result, utils::stream::IterStream};
8
9use super::format_count_etag;
10use crate::Ruma;
11
12/// # `PUT /_matrix/client/r0/room_keys/keys`
13///
14/// Add the received backup keys to the database.
15///
16/// - Only manipulating the most recently created version of the backup is
17///   allowed
18/// - Adds the keys to the backup
19/// - Returns the new number of keys in this backup and the etag
20pub(crate) async fn add_backup_keys_route(
21	State(services): State<crate::State>,
22	body: Ruma<add_backup_keys::v3::Request>,
23) -> Result<add_backup_keys::v3::Response> {
24	let keys = body
25		.rooms
26		.iter()
27		.flat_map(|(room_id, room)| {
28			room.sessions
29				.iter()
30				.map(move |(session_id, key_data)| (room_id, session_id, key_data))
31		})
32		.map(|(room_id, session_id, key_data)| (room_id.as_ref(), session_id.as_str(), key_data))
33		.stream();
34
35	let metadata = services
36		.key_backups
37		.add_keys(body.sender_user(), &body.version, keys)
38		.await?;
39
40	let (count, etag) = format_count_etag(metadata)?;
41
42	Ok(AddResponse { count, etag })
43}
44
45/// # `GET /_matrix/client/r0/room_keys/keys`
46///
47/// Retrieves all keys from the backup.
48pub(crate) async fn get_backup_keys_route(
49	State(services): State<crate::State>,
50	body: Ruma<get_backup_keys::v3::Request>,
51) -> Result<get_backup_keys::v3::Response> {
52	let rooms = services
53		.key_backups
54		.get_all(body.sender_user(), &body.version)
55		.await;
56
57	Ok(GetResponse { rooms })
58}
59
60/// # `DELETE /_matrix/client/r0/room_keys/keys`
61///
62/// Delete the keys from the backup.
63pub(crate) async fn delete_backup_keys_route(
64	State(services): State<crate::State>,
65	body: Ruma<delete_backup_keys::v3::Request>,
66) -> Result<delete_backup_keys::v3::Response> {
67	let metadata = services
68		.key_backups
69		.delete_all_keys(body.sender_user(), &body.version)
70		.await?;
71
72	let (count, etag) = format_count_etag(metadata)?;
73
74	Ok(DeleteResponse { count, etag })
75}