From f3031a2a951978b08c9bea96ea7cb92e4773988f Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 10 Feb 2023 08:27:58 -0500 Subject: [PATCH] Update intentional mentions (MSC3952) to depend on `exact_event_property_contains` (MSC3966). --- rust/src/push/base_rules.rs | 11 +++++++++-- rust/src/push/evaluator.rs | 31 +++++++++++++++++++++++++++---- rust/src/push/mod.rs | 5 ++++- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/rust/src/push/base_rules.rs b/rust/src/push/base_rules.rs index 5aa2ad2ff067..40b75b17c132 100644 --- a/rust/src/push/base_rules.rs +++ b/rust/src/push/base_rules.rs @@ -151,7 +151,13 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[ PushRule { rule_id: Cow::Borrowed(".org.matrix.msc3952.is_user_mention"), priority_class: 5, - conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::IsUserMention)]), + conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::ExactEventMatch( + ExactEventMatchCondition { + key: Cow::Borrowed("content.org.matrix.msc3952.mentions.user_ids"), + value: None, + value_type: Some(Cow::Borrowed("user_id")), + }, + ))]), actions: Cow::Borrowed(&[Action::Notify, HIGHLIGHT_ACTION, SOUND_ACTION]), default: true, default_enabled: true, @@ -170,7 +176,8 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[ conditions: Cow::Borrowed(&[ Condition::Known(KnownCondition::ExactEventMatch(ExactEventMatchCondition { key: Cow::Borrowed("content.org.matrix.msc3952.mentions.room"), - value: Cow::Borrowed(&SimpleJsonValue::Bool(true)), + value: Some(Cow::Borrowed(&SimpleJsonValue::Bool(true))), + value_type: None, })), Condition::Known(KnownCondition::SenderNotificationPermission { key: Cow::Borrowed("room"), diff --git a/rust/src/push/evaluator.rs b/rust/src/push/evaluator.rs index 55551ecb56a7..e7db48e93bcc 100644 --- a/rust/src/push/evaluator.rs +++ b/rust/src/push/evaluator.rs @@ -266,7 +266,7 @@ impl PushRuleEvaluator { self.match_related_event_match(event_match, user_id)? } KnownCondition::ExactEventPropertyContains(exact_event_match) => { - self.match_exact_event_property_contains(exact_event_match)? + self.match_exact_event_property_contains(exact_event_match, user_id)? } KnownCondition::IsUserMention => { if let Some(uid) = user_id { @@ -379,7 +379,12 @@ impl PushRuleEvaluator { return Ok(false); } - let value = &exact_event_match.value; + // exact_event_match requires a value to be set. + let value = if let Some(value) = &exact_event_match.value { + value + } else { + return Ok(false); + }; let haystack = if let Some(JsonValue::Value(haystack)) = self.flattened_keys.get(&*exact_event_match.key) @@ -470,13 +475,31 @@ impl PushRuleEvaluator { fn match_exact_event_property_contains( &self, exact_event_match: &ExactEventMatchCondition, + user_id: Option<&str>, ) -> Result { // First check if the feature is enabled. if !self.msc3966_exact_event_property_contains { return Ok(false); } - let value = &exact_event_match.value; + let value = if let Some(value) = &exact_event_match.value { + &**value + } else if let Some(value_type) = &exact_event_match.value_type { + // The `value_type` must be "user_id", if we don't have a `user_id` + // then the condition can't match. + let user_id = if let Some(user_id) = user_id { + &SimpleJsonValue::Str(user_id.to_string()) + } else { + return Ok(false); + }; + + match &**value_type { + "user_id" => user_id, + _ => return Ok(false), + } + } else { + return Ok(false); + }; let haystack = if let Some(JsonValue::Array(haystack)) = self.flattened_keys.get(&*exact_event_match.key) @@ -486,7 +509,7 @@ impl PushRuleEvaluator { return Ok(false); }; - Ok(haystack.contains(&**value)) + Ok(haystack.contains(value)) } /// Match the member count against an 'is' condition diff --git a/rust/src/push/mod.rs b/rust/src/push/mod.rs index e6d12891e9c9..9c8e7ad6eccd 100644 --- a/rust/src/push/mod.rs +++ b/rust/src/push/mod.rs @@ -378,7 +378,10 @@ pub struct EventMatchCondition { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ExactEventMatchCondition { pub key: Cow<'static, str>, - pub value: Cow<'static, SimpleJsonValue>, + #[serde(skip_serializing_if = "Option::is_none")] + pub value: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub value_type: Option>, } /// The body of a [`Condition::RelatedEventMatch`]