tuwunel_api/client/push/
pushrules_rule.rs1use axum::extract::State;
2use ruma::{
3 api::client::push::{
4 delete_pushrule,
5 get_pushrule::{self, v3::Response},
6 set_pushrule,
7 },
8 push::{InsertPushRuleError, RemovePushRuleError},
9};
10use tuwunel_core::{Err, Result};
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<Response> {
21 let sender_user = body
22 .sender_user
23 .as_ref()
24 .expect("user is authenticated");
25
26 if super::is_deprecated_mention_rule(body.rule_id.as_str()) {
27 return Err!(Request(NotFound("Push rule not found.")));
28 }
29
30 let event = super::load_push_rules(&services, sender_user).await?;
31
32 event
33 .content
34 .global
35 .get(body.kind.clone(), &body.rule_id)
36 .map(Into::into)
37 .map_or_else(
38 || Err!(Request(NotFound("Push rule not found."))),
39 |rule| Ok(Response { rule }),
40 )
41}
42
43pub(crate) async fn set_pushrule_route(
47 State(services): State<crate::State>,
48 body: Ruma<set_pushrule::v3::Request>,
49) -> Result<set_pushrule::v3::Response> {
50 let sender_user = body.sender_user();
51 let mut account_data = super::load_push_rules(&services, sender_user).await?;
52
53 super::check_rule_admission(&account_data.content.global, &body.rule)?;
54
55 if let Err(error) = account_data.content.global.insert(
56 body.rule.clone(),
57 body.after.as_deref(),
58 body.before.as_deref(),
59 ) {
60 use InsertPushRuleError::*;
61
62 return match error {
63 | ServerDefaultRuleId => Err!(Request(InvalidParam(
64 "Rule IDs starting with a dot are reserved for server-default rules."
65 ))),
66 | RelativeToServerDefaultRule => Err!(Request(InvalidParam(
67 "Can't place a push rule relatively to a server-default rule."
68 ))),
69 | BeforeHigherThanAfter => Err!(Request(InvalidParam(
70 "The before rule has a higher priority than the after rule."
71 ))),
72 | InvalidRuleId =>
73 Err!(Request(InvalidParam("Rule ID containing invalid characters."))),
74
75 | UnknownRuleId =>
76 Err!(Request(NotFound("The before or after rule could not be found."))),
77
78 | _ => Err!(Request(InvalidParam("Invalid data."))),
79 };
80 }
81
82 super::check_rule_size(&account_data.content.global, body.rule.kind(), body.rule.rule_id())?;
83
84 super::save_push_rules(&services, sender_user, &account_data).await?;
85
86 Ok(set_pushrule::v3::Response {})
87}
88
89pub(crate) async fn delete_pushrule_route(
93 State(services): State<crate::State>,
94 body: Ruma<delete_pushrule::v3::Request>,
95) -> Result<delete_pushrule::v3::Response> {
96 let sender_user = body.sender_user();
97 let mut account_data = super::load_push_rules(&services, sender_user).await?;
98
99 if let Err(error) = account_data
100 .content
101 .global
102 .remove(body.kind.clone(), &body.rule_id)
103 {
104 return match error {
105 | RemovePushRuleError::ServerDefault =>
106 Err!(Request(InvalidParam("Cannot delete a server-default pushrule."))),
107
108 | RemovePushRuleError::NotFound => Err!(Request(NotFound("Push rule not found."))),
109
110 | _ => Err!(Request(InvalidParam("Invalid data."))),
111 };
112 }
113
114 super::save_push_rules(&services, sender_user, &account_data).await?;
115
116 Ok(delete_pushrule::v3::Response {})
117}