tuwunel_api/client/account_data/
mod.rs1mod delete_global_account_data;
2mod delete_room_account_data;
3mod get_global_account_data;
4mod get_room_account_data;
5mod set_global_account_data;
6mod set_room_account_data;
7
8use ruma::{
9 RoomId, UserId,
10 events::{GlobalAccountDataEventType, RoomAccountDataEventType},
11 serde::Raw,
12};
13use serde::Deserialize;
14use serde_json::{Value as JsonValue, json, value::RawValue as RawJsonValue};
15use tuwunel_core::{Err, Result, err};
16use tuwunel_service::Services;
17
18pub(crate) use self::{
19 delete_global_account_data::delete_global_account_data_route,
20 delete_room_account_data::delete_room_account_data_route,
21 get_global_account_data::get_global_account_data_route,
22 get_room_account_data::get_room_account_data_route,
23 set_global_account_data::set_global_account_data_route,
24 set_room_account_data::set_room_account_data_route,
25};
26
27async fn set_account_data(
28 services: &Services,
29 room_id: Option<&RoomId>,
30 sender_user: &UserId,
31 event_type_s: &str,
32 data: &RawJsonValue,
33) -> Result {
34 if event_type_s == RoomAccountDataEventType::FullyRead.to_cow_str() {
35 return Err!(Request(BadJson(
36 "This endpoint cannot be used for marking a room as fully read (setting \
37 m.fully_read)"
38 )));
39 }
40
41 if event_type_s == GlobalAccountDataEventType::PushRules.to_cow_str() {
42 return Err!(Request(BadJson(
43 "This endpoint cannot be used for setting/configuring push rules."
44 )));
45 }
46
47 let data: serde_json::Value = serde_json::from_str(data.get())
48 .map_err(|e| err!(Request(BadJson(warn!("Invalid JSON provided: {e}")))))?;
49
50 services
51 .account_data
52 .update(
53 room_id,
54 sender_user,
55 event_type_s.into(),
56 &json!({
57 "type": event_type_s,
58 "content": data,
59 }),
60 )
61 .await
62}
63
64fn is_empty_content<T>(content: &Raw<T>) -> bool { is_empty_object_json(content.json()) }
68
69pub(crate) fn is_empty_account_data_event<T>(event: &Raw<T>) -> bool {
72 #[derive(Deserialize)]
73 struct ContentOnly<'a> {
74 #[serde(borrow)]
75 content: &'a RawJsonValue,
76 }
77
78 serde_json::from_str::<ContentOnly<'_>>(event.json().get())
79 .is_ok_and(|c| is_empty_object_json(c.content))
80}
81
82fn is_empty_object_json(s: &RawJsonValue) -> bool {
83 serde_json::from_str::<JsonValue>(s.get())
84 .ok()
85 .and_then(|v| v.as_object().map(serde_json::Map::is_empty))
86 .unwrap_or(false)
87}