tuwunel_api/client/push/
pushrules_rule.rs1use axum::extract::State;
2use ruma::{
3 api::client::push::{delete_pushrule, get_pushrule, set_pushrule},
4 events::{GlobalAccountDataEventType, push_rules::PushRulesEvent},
5 push::{
6 InsertPushRuleError, PredefinedContentRuleId, PredefinedOverrideRuleId,
7 RemovePushRuleError,
8 },
9};
10use tuwunel_core::{Err, Result, err};
11
12use crate::Ruma;
13
14pub(crate) async fn get_pushrule_route(
18 State(services): State<crate::State>,
19 body: Ruma<get_pushrule::v3::Request>,
20) -> Result<get_pushrule::v3::Response> {
21 let sender_user = body
22 .sender_user
23 .as_ref()
24 .expect("user is authenticated");
25
26 #[expect(deprecated)]
28 if body.rule_id.as_str() == PredefinedContentRuleId::ContainsUserName.as_str()
29 || body.rule_id.as_str() == PredefinedOverrideRuleId::ContainsDisplayName.as_str()
30 || body.rule_id.as_str() == PredefinedOverrideRuleId::RoomNotif.as_str()
31 {
32 return Err!(Request(NotFound("Push rule not found.")));
33 }
34
35 let event: PushRulesEvent = services
36 .account_data
37 .get_global(sender_user, GlobalAccountDataEventType::PushRules)
38 .await
39 .map_err(|_| err!(Request(NotFound("PushRules event not found."))))?;
40
41 let rule = event
42 .content
43 .global
44 .get(body.kind.clone(), &body.rule_id)
45 .map(Into::into);
46
47 if let Some(rule) = rule {
48 Ok(get_pushrule::v3::Response { rule })
49 } else {
50 Err!(Request(NotFound("Push rule not found.")))
51 }
52}
53
54pub(crate) async fn set_pushrule_route(
58 State(services): State<crate::State>,
59 body: Ruma<set_pushrule::v3::Request>,
60) -> Result<set_pushrule::v3::Response> {
61 let sender_user = body.sender_user();
62 let mut account_data: PushRulesEvent = services
63 .account_data
64 .get_global(sender_user, GlobalAccountDataEventType::PushRules)
65 .await
66 .map_err(|_| err!(Request(NotFound("PushRules event not found."))))?;
67
68 if let Err(error) = account_data.content.global.insert(
69 body.rule.clone(),
70 body.after.as_deref(),
71 body.before.as_deref(),
72 ) {
73 use InsertPushRuleError::*;
74
75 return match error {
76 | ServerDefaultRuleId => Err!(Request(InvalidParam(
77 "Rule IDs starting with a dot are reserved for server-default rules."
78 ))),
79 | RelativeToServerDefaultRule => Err!(Request(InvalidParam(
80 "Can't place a push rule relatively to a server-default rule."
81 ))),
82 | BeforeHigherThanAfter => Err!(Request(InvalidParam(
83 "The before rule has a higher priority than the after rule."
84 ))),
85 | InvalidRuleId =>
86 Err!(Request(InvalidParam("Rule ID containing invalid characters."))),
87
88 | UnknownRuleId =>
89 Err!(Request(NotFound("The before or after rule could not be found."))),
90
91 | _ => Err!(Request(InvalidParam("Invalid data."))),
92 };
93 }
94
95 let ty = GlobalAccountDataEventType::PushRules;
96 services
97 .account_data
98 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(account_data)?)
99 .await?;
100
101 Ok(set_pushrule::v3::Response {})
102}
103
104pub(crate) async fn delete_pushrule_route(
108 State(services): State<crate::State>,
109 body: Ruma<delete_pushrule::v3::Request>,
110) -> Result<delete_pushrule::v3::Response> {
111 let sender_user = body.sender_user();
112
113 let mut account_data: PushRulesEvent = services
114 .account_data
115 .get_global(sender_user, GlobalAccountDataEventType::PushRules)
116 .await
117 .map_err(|_| err!(Request(NotFound("PushRules event not found."))))?;
118
119 if let Err(error) = account_data
120 .content
121 .global
122 .remove(body.kind.clone(), &body.rule_id)
123 {
124 return match error {
125 | RemovePushRuleError::ServerDefault =>
126 Err!(Request(InvalidParam("Cannot delete a server-default pushrule."))),
127
128 | RemovePushRuleError::NotFound => Err!(Request(NotFound("Push rule not found."))),
129
130 | _ => Err!(Request(InvalidParam("Invalid data."))),
131 };
132 }
133
134 let ty = GlobalAccountDataEventType::PushRules;
135 services
136 .account_data
137 .update(None, sender_user, ty.to_string().into(), &serde_json::to_value(account_data)?)
138 .await?;
139
140 Ok(delete_pushrule::v3::Response {})
141}