From 63193840729ab1dea026514d807aa39a98b3f1b1 Mon Sep 17 00:00:00 2001 From: strawberry Date: Fri, 15 Nov 2024 21:40:13 -0500 Subject: [PATCH] implement `GET /_matrix/client/v3/pushrules/global/` Signed-off-by: strawberry --- src/api/client/push.rs | 69 +++++++++++++++++++++++++++++++++++++++++- src/api/router.rs | 1 + 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/api/client/push.rs b/src/api/client/push.rs index de280b32..97243ab4 100644 --- a/src/api/client/push.rs +++ b/src/api/client/push.rs @@ -5,7 +5,7 @@ use ruma::{ error::ErrorKind, push::{ delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all, - set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled, + get_pushrules_global_scope, set_pusher, set_pushrule, set_pushrule_actions, set_pushrule_enabled, }, }, events::{ @@ -67,6 +67,73 @@ pub(crate) async fn get_pushrules_all_route( }) } +/// # `GET /_matrix/client/r0/pushrules/global/` +/// +/// Retrieves the push rules event for this user. +/// +/// This appears to be the exact same as `GET /_matrix/client/r0/pushrules/`. +pub(crate) async fn get_pushrules_global_route( + State(services): State, body: Ruma, +) -> Result { + let sender_user = body.sender_user.as_ref().expect("user is authenticated"); + + let Some(content_value) = services + .account_data + .get_global::(sender_user, GlobalAccountDataEventType::PushRules) + .await + .ok() + .and_then(|event| event.get("content").cloned()) + .filter(CanonicalJsonValue::is_object) + else { + // user somehow has non-existent push rule event. recreate it and return server + // default silently + services + .account_data + .update( + None, + sender_user, + GlobalAccountDataEventType::PushRules.to_string().into(), + &serde_json::to_value(PushRulesEvent { + content: PushRulesEventContent { + global: Ruleset::server_default(sender_user), + }, + }) + .expect("to json always works"), + ) + .await?; + + return Ok(get_pushrules_global_scope::v3::Response { + global: Ruleset::server_default(sender_user), + }); + }; + + let account_data_content = serde_json::from_value::(content_value.into()) + .map_err(|e| err!(Database(warn!("Invalid push rules account data event in database: {e}"))))?; + + let mut global_ruleset = account_data_content.global; + + // remove old deprecated mentions push rules as per MSC4210 + #[allow(deprecated)] + { + use ruma::push::RuleKind::*; + + global_ruleset + .remove(Override, PredefinedOverrideRuleId::ContainsDisplayName) + .ok(); + global_ruleset + .remove(Override, PredefinedOverrideRuleId::RoomNotif) + .ok(); + + global_ruleset + .remove(Content, PredefinedContentRuleId::ContainsUserName) + .ok(); + }; + + Ok(get_pushrules_global_scope::v3::Response { + global: global_ruleset, + }) +} + /// # `GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}` /// /// Retrieves a single specified push rule for this user. diff --git a/src/api/router.rs b/src/api/router.rs index ddd91d11..1df4342f 100644 --- a/src/api/router.rs +++ b/src/api/router.rs @@ -45,6 +45,7 @@ pub fn build(router: Router, server: &Server) -> Router { .ruma_route(&client::check_registration_token_validity) .ruma_route(&client::get_capabilities_route) .ruma_route(&client::get_pushrules_all_route) + .ruma_route(&client::get_pushrules_global_route) .ruma_route(&client::set_pushrule_route) .ruma_route(&client::get_pushrule_route) .ruma_route(&client::set_pushrule_enabled_route)