Skip to main content

tuwunel_api/client/backup/
keys.rs

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