tuwunel_api/client/push/
pushrules.rs1use axum::extract::State;
2use ruma::{
3 CanonicalJsonObject, CanonicalJsonValue,
4 api::client::push::get_pushrules_all,
5 events::{
6 GlobalAccountDataEventType,
7 push_rules::{PushRulesEvent, PushRulesEventContent},
8 },
9 push::{PredefinedContentRuleId, PredefinedOverrideRuleId, Ruleset},
10};
11use tuwunel_core::{Result, err};
12use tuwunel_service::Services;
13
14use crate::Ruma;
15
16pub(crate) async fn get_pushrules_all_route(
20 State(services): State<crate::State>,
21 body: Ruma<get_pushrules_all::v3::Request>,
22) -> Result<get_pushrules_all::v3::Response> {
23 let sender_user = body.sender_user();
24
25 let Some(content_value) = services
26 .account_data
27 .get_global::<CanonicalJsonObject>(sender_user, GlobalAccountDataEventType::PushRules)
28 .await
29 .ok()
30 .and_then(|event| event.get("content").cloned())
31 .filter(CanonicalJsonValue::is_object)
32 else {
33 return recreate_push_rules_and_return(&services, sender_user).await;
36 };
37
38 let account_data_content =
39 serde_json::from_value::<PushRulesEventContent>(content_value.into()).map_err(|e| {
40 err!(Database(warn!("Invalid push rules account data event in database: {e}")))
41 })?;
42
43 let mut global_ruleset = account_data_content.global;
44
45 #[expect(deprecated)]
48 {
49 use ruma::push::RuleKind::*;
50 if global_ruleset
51 .get(Override, PredefinedOverrideRuleId::ContainsDisplayName.as_str())
52 .is_some()
53 || global_ruleset
54 .get(Override, PredefinedOverrideRuleId::RoomNotif.as_str())
55 .is_some()
56 || global_ruleset
57 .get(Content, PredefinedContentRuleId::ContainsUserName.as_str())
58 .is_some()
59 {
60 global_ruleset
61 .remove(Override, PredefinedOverrideRuleId::ContainsDisplayName)
62 .ok();
63 global_ruleset
64 .remove(Override, PredefinedOverrideRuleId::RoomNotif)
65 .ok();
66 global_ruleset
67 .remove(Content, PredefinedContentRuleId::ContainsUserName)
68 .ok();
69
70 global_ruleset.update_with_server_default(Ruleset::server_default(sender_user));
71
72 let ty = GlobalAccountDataEventType::PushRules;
73 let event = PushRulesEvent {
74 content: PushRulesEventContent { global: global_ruleset.clone() },
75 };
76
77 services
78 .account_data
79 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(event)?)
80 .await?;
81 }
82 };
83
84 Ok(get_pushrules_all::v3::Response { global: global_ruleset })
85}
86
87async fn recreate_push_rules_and_return(
90 services: &Services,
91 sender_user: &ruma::UserId,
92) -> Result<get_pushrules_all::v3::Response> {
93 let ty = GlobalAccountDataEventType::PushRules;
94 let event = PushRulesEvent {
95 content: PushRulesEventContent {
96 global: Ruleset::server_default(sender_user),
97 },
98 };
99
100 services
101 .account_data
102 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(event)?)
103 .await?;
104
105 Ok(get_pushrules_all::v3::Response {
106 global: Ruleset::server_default(sender_user),
107 })
108}