tuwunel_service/account_data/
push_rules.rs1use ruma::{
2 RoomId, UserId,
3 events::{GlobalAccountDataEventType, push_rules::PushRulesEvent},
4 push::{AnyPushRuleRef, NewPushRule, NewSimplePushRule, RuleKind},
5};
6use tuwunel_core::{Result, debug_warn, err, implement, utils::json::serialized_len};
7
8use super::{MAX_RULE_BYTES, admits_rule};
9
10#[implement(super::Service)]
11pub async fn copy_room_push_rule(
12 &self,
13 user_id: &UserId,
14 from_room: &RoomId,
15 to_room: &RoomId,
16) -> Result {
17 let Ok(mut account_data): Result<PushRulesEvent> = self
18 .get_global(user_id, GlobalAccountDataEventType::PushRules)
19 .await
20 else {
21 return Ok(());
22 };
23
24 let ruleset = &mut account_data.content.global;
25
26 let Some(AnyPushRuleRef::Room(rule)) = ruleset.get(RuleKind::Room, from_room) else {
27 return Ok(());
28 };
29
30 let actions = rule.actions.clone();
31
32 if !admits_rule(ruleset, RuleKind::Room, to_room.as_str())
33 || serialized_len(&actions)? > MAX_RULE_BYTES
34 {
35 debug_warn!(%user_id, %to_room, "Ruleset has no room for the copied push rule");
36
37 return Ok(());
38 }
39
40 let rule = NewPushRule::Room(NewSimplePushRule::new(to_room.to_owned(), actions));
41
42 ruleset
43 .insert(rule, None, None)
44 .map_err(|e| err!(Request(InvalidParam("Failed to copy room push rule: {e}"))))?;
45
46 let ty = GlobalAccountDataEventType::PushRules;
47 let data = serde_json::to_value(account_data)?;
48
49 self.update(None, user_id, ty.to_string().into(), &data)
50 .await
51}