diff --git a/changelog.d/19954.feature b/changelog.d/19954.feature new file mode 100644 index 00000000000..7a87e557663 --- /dev/null +++ b/changelog.d/19954.feature @@ -0,0 +1 @@ +Add experimental support for [MSC4505](https://github.com/matrix-org/matrix-spec-proposals/pull/4505): push rules for live location sharing. diff --git a/rust/benches/evaluator.rs b/rust/benches/evaluator.rs index 96169fd45d9..e59a6d2f6ab 100644 --- a/rust/benches/evaluator.rs +++ b/rust/benches/evaluator.rs @@ -215,6 +215,7 @@ fn bench_eval_message(b: &mut Bencher) { false, false, false, + false, ); b.iter(|| eval.run(&rules, Some("bob"), Some("person"), None)); diff --git a/rust/src/push/base_rules.rs b/rust/src/push/base_rules.rs index 47d5289006b..c71e57b0be9 100644 --- a/rust/src/push/base_rules.rs +++ b/rust/src/push/base_rules.rs @@ -273,6 +273,22 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[ default: true, default_enabled: true, }, + // MSC4505: explicitly suppress live location share beacon updates in unencrypted + // rooms (in encrypted rooms they arrive as m.room.encrypted and can only be + // suppressed client-side after decryption). + PushRule { + rule_id: Cow::Borrowed("global/override/.org.matrix.msc4505.rule.beacon"), + priority_class: 5, + conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::EventMatch( + EventMatchCondition { + key: Cow::Borrowed("type"), + pattern: Cow::Borrowed("org.matrix.msc3672.beacon"), + }, + ))]), + actions: Cow::Borrowed(&[]), + default: true, + default_enabled: true, + }, ]; pub const BASE_APPEND_CONTENT_RULES: &[PushRule] = &[PushRule { @@ -721,6 +737,43 @@ pub const BASE_APPEND_UNDERRIDE_RULES: &[PushRule] = &[ default: true, default_enabled: true, }, + PushRule { + rule_id: Cow::Borrowed("global/underride/.org.matrix.msc4505.rule.beacon_info_one_to_one"), + priority_class: 1, + conditions: Cow::Borrowed(&[ + Condition::Known(KnownCondition::RoomMemberCount { + is: Some(Cow::Borrowed("2")), + }), + Condition::Known(KnownCondition::EventMatch(EventMatchCondition { + key: Cow::Borrowed("type"), + pattern: Cow::Borrowed("org.matrix.msc3672.beacon_info"), + })), + Condition::Known(KnownCondition::EventPropertyIs(EventPropertyIsCondition { + key: Cow::Borrowed("content.live"), + value: Cow::Owned(SimpleJsonValue::Bool(true)), + })), + ]), + actions: Cow::Borrowed(&[Action::Notify, SOUND_ACTION]), + default: true, + default_enabled: true, + }, + PushRule { + rule_id: Cow::Borrowed("global/underride/.org.matrix.msc4505.rule.beacon_info"), + priority_class: 1, + conditions: Cow::Borrowed(&[ + Condition::Known(KnownCondition::EventMatch(EventMatchCondition { + key: Cow::Borrowed("type"), + pattern: Cow::Borrowed("org.matrix.msc3672.beacon_info"), + })), + Condition::Known(KnownCondition::EventPropertyIs(EventPropertyIsCondition { + key: Cow::Borrowed("content.live"), + value: Cow::Owned(SimpleJsonValue::Bool(true)), + })), + ]), + actions: Cow::Borrowed(&[Action::Notify]), + default: true, + default_enabled: true, + }, ]; lazy_static! { diff --git a/rust/src/push/evaluator.rs b/rust/src/push/evaluator.rs index 1cbca4c6355..250d2890c09 100644 --- a/rust/src/push/evaluator.rs +++ b/rust/src/push/evaluator.rs @@ -637,6 +637,7 @@ fn test_requires_room_version_supports_condition() { false, false, false, + false, ), None, None, diff --git a/rust/src/push/mod.rs b/rust/src/push/mod.rs index 780d7a8cbd8..2854dd6e889 100644 --- a/rust/src/push/mod.rs +++ b/rust/src/push/mod.rs @@ -559,6 +559,7 @@ pub struct FilteredPushRules { msc4028_push_encrypted_events: bool, msc4210_enabled: bool, msc4306_enabled: bool, + msc4505_enabled: bool, } #[pymethods] @@ -574,6 +575,7 @@ impl FilteredPushRules { msc4028_push_encrypted_events: bool, msc4210_enabled: bool, msc4306_enabled: bool, + msc4505_enabled: bool, ) -> Self { Self { push_rules, @@ -584,6 +586,7 @@ impl FilteredPushRules { msc4028_push_encrypted_events, msc4210_enabled, msc4306_enabled, + msc4505_enabled, } } @@ -620,6 +623,12 @@ impl FilteredPushRules { return false; } + if !self.msc4505_enabled + && rule.rule_id.contains("/.org.matrix.msc4505.rule.beacon") + { + return false; + } + if !self.msc4028_push_encrypted_events && rule.rule_id == "global/override/.org.matrix.msc4028.encrypted_event" { diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py index f99f7b139ec..c1c83100676 100644 --- a/synapse/config/experimental.py +++ b/synapse/config/experimental.py @@ -156,6 +156,12 @@ def read_config( "msc3381_polls_enabled", False ) + # MSC4505: default push rules for live location sharing — notify on + # beacon_info start events (the MSC3672 state event), suppress beacon + # updates. Unstable rule ids: .org.matrix.msc4505.rule.beacon_info + # (_one_to_one) / .org.matrix.msc4505.rule.beacon. + self.msc4505_enabled: bool = experimental.get("msc4505_enabled", False) + # MSC3912: Relation-based redactions. self.msc3912_enabled: bool = experimental.get("msc3912_enabled", False) diff --git a/synapse/storage/databases/main/push_rule.py b/synapse/storage/databases/main/push_rule.py index d361166cec4..6aa1baa5a64 100644 --- a/synapse/storage/databases/main/push_rule.py +++ b/synapse/storage/databases/main/push_rule.py @@ -107,6 +107,7 @@ def _load_rules( msc4028_push_encrypted_events=experimental_config.msc4028_push_encrypted_events, msc4210_enabled=experimental_config.msc4210_enabled, msc4306_enabled=experimental_config.msc4306_enabled, + msc4505_enabled=experimental_config.msc4505_enabled, ) return filtered_rules diff --git a/synapse/synapse_rust/push.pyi b/synapse/synapse_rust/push.pyi index ef0d5f94f4f..8799d08a151 100644 --- a/synapse/synapse_rust/push.pyi +++ b/synapse/synapse_rust/push.pyi @@ -50,6 +50,7 @@ class FilteredPushRules: msc4028_push_encrypted_events: bool, msc4210_enabled: bool, msc4306_enabled: bool, + msc4505_enabled: bool, ): ... def rules(self) -> Collection[tuple[PushRule, bool]]: ...