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 || global_ruleset
60 .get(Override, PredefinedOverrideRuleId::Reply.as_str())
61 .is_none()
62 {
63 global_ruleset
64 .remove(Override, PredefinedOverrideRuleId::ContainsDisplayName)
65 .ok();
66 global_ruleset
67 .remove(Override, PredefinedOverrideRuleId::RoomNotif)
68 .ok();
69 global_ruleset
70 .remove(Content, PredefinedContentRuleId::ContainsUserName)
71 .ok();
72
73 global_ruleset.update_with_server_default(Ruleset::server_default(sender_user));
74
75 let ty = GlobalAccountDataEventType::PushRules;
76 let event = PushRulesEvent {
77 content: PushRulesEventContent { global: global_ruleset.clone() },
78 };
79
80 services
81 .account_data
82 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(event)?)
83 .await?;
84 }
85 };
86
87 Ok(get_pushrules_all::v3::Response { global: global_ruleset })
88}
89
90async fn recreate_push_rules_and_return(
93 services: &Services,
94 sender_user: &ruma::UserId,
95) -> Result<get_pushrules_all::v3::Response> {
96 let ty = GlobalAccountDataEventType::PushRules;
97 let event = PushRulesEvent {
98 content: PushRulesEventContent {
99 global: Ruleset::server_default(sender_user),
100 },
101 };
102
103 services
104 .account_data
105 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(event)?)
106 .await?;
107
108 Ok(get_pushrules_all::v3::Response {
109 global: Ruleset::server_default(sender_user),
110 })
111}