Skip to main content

tuwunel_api/client/backup/
keys_session.rs

1use std::iter::once;
2
3use axum::extract::State;
4use ruma::api::client::backup::{
5	add_backup_keys_for_session::{self, v3::Response as AddResponse},
6	delete_backup_keys_for_session::{self, v3::Response as DeleteResponse},
7	get_backup_keys_for_session::{self, v3::Response as GetResponse},
8};
9use tuwunel_core::{Result, err, utils::stream::IterStream};
10
11use super::format_count_etag;
12use crate::Ruma;
13
14/// # `PUT /_matrix/client/r0/room_keys/keys/{roomId}/{sessionId}`
15///
16/// Add the received backup key to the database.
17///
18/// - Only manipulating the most recently created version of the backup is
19///   allowed
20/// - Adds the keys to the backup
21/// - Returns the new number of keys in this backup and the etag
22pub(crate) async fn add_backup_keys_for_session_route(
23	State(services): State<crate::State>,
24	body: Ruma<add_backup_keys_for_session::v3::Request>,
25) -> Result<add_backup_keys_for_session::v3::Response> {
26	let keys =
27		once((body.room_id.as_ref(), body.session_id.as_str(), &body.session_data)).stream();
28
29	let metadata = services
30		.key_backups
31		.add_keys(body.sender_user(), &body.version, keys)
32		.await?;
33
34	let (count, etag) = format_count_etag(metadata)?;
35
36	Ok(AddResponse { count, etag })
37}
38
39/// # `GET /_matrix/client/r0/room_keys/keys/{roomId}/{sessionId}`
40///
41/// Retrieves a key from the backup.
42pub(crate) async fn get_backup_keys_for_session_route(
43	State(services): State<crate::State>,
44	body: Ruma<get_backup_keys_for_session::v3::Request>,
45) -> Result<get_backup_keys_for_session::v3::Response> {
46	let key_data = services
47		.key_backups
48		.get_session(body.sender_user(), &body.version, &body.room_id, &body.session_id)
49		.await
50		.map_err(|error| {
51			if error.is_not_found() {
52				err!(Request(NotFound(debug_error!(
53					"Backup key not found for this user's session."
54				))))
55			} else {
56				error
57			}
58		})?;
59
60	Ok(GetResponse { key_data })
61}
62
63/// # `DELETE /_matrix/client/r0/room_keys/keys/{roomId}/{sessionId}`
64///
65/// Delete a key from the backup.
66pub(crate) async fn delete_backup_keys_for_session_route(
67	State(services): State<crate::State>,
68	body: Ruma<delete_backup_keys_for_session::v3::Request>,
69) -> Result<delete_backup_keys_for_session::v3::Response> {
70	let metadata = services
71		.key_backups
72		.delete_room_key(body.sender_user(), &body.version, &body.room_id, &body.session_id)
73		.await?;
74
75	let (count, etag) = format_count_etag(metadata)?;
76
77	Ok(DeleteResponse { count, etag })
78}