Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit dd51828

Browse files
authored
Create MSC1767 (extensible events) room version; Implement MSC3932 (#14521)
* Add MSC1767's dedicated room version, based on v10 * Only enable MSC1767 room version if the config flag is on Using a similar technique to knocking: https://github.com/matrix-org/synapse/pull/6739/files#diff-3af529eedb0e00279bafb7369370c9654b37792af8eafa0925400e9281d57f0a * Support MSC3932: Extensible events room version feature flag * Changelog entry
1 parent 3da6450 commit dd51828

File tree

4 files changed

+130
-2
lines changed

4 files changed

+130
-2
lines changed

changelog.d/14521.feature

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add unstable support for an Extensible Events room version (`org.matrix.msc1767.10`) via [MSC1767](https://github.com/matrix-org/matrix-spec-proposals/pull/1767), [MSC3931](https://github.com/matrix-org/matrix-spec-proposals/pull/3931), [MSC3932](https://github.com/matrix-org/matrix-spec-proposals/pull/3932), and [MSC3933](https://github.com/matrix-org/matrix-spec-proposals/pull/3933).

rust/src/push/evaluator.rs

+96-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::borrow::Cow;
1516
use std::collections::BTreeMap;
1617

18+
use crate::push::{PushRule, PushRules};
1719
use anyhow::{Context, Error};
1820
use lazy_static::lazy_static;
1921
use log::warn;
@@ -32,7 +34,30 @@ lazy_static! {
3234

3335
/// Used to determine which MSC3931 room version feature flags are actually known to
3436
/// the push evaluator.
35-
static ref KNOWN_RVER_FLAGS: Vec<String> = vec![];
37+
static ref KNOWN_RVER_FLAGS: Vec<String> = vec![
38+
RoomVersionFeatures::ExtensibleEvents.as_str().to_string(),
39+
];
40+
41+
/// The "safe" rule IDs which are not affected by MSC3932's behaviour (room versions which
42+
/// declare Extensible Events support ultimately *disable* push rules which do not declare
43+
/// *any* MSC3931 room_version_supports condition).
44+
static ref SAFE_EXTENSIBLE_EVENTS_RULE_IDS: Vec<String> = vec![
45+
"global/override/.m.rule.master".to_string(),
46+
"global/override/.m.rule.roomnotif".to_string(),
47+
"global/content/.m.rule.contains_user_name".to_string(),
48+
];
49+
}
50+
51+
enum RoomVersionFeatures {
52+
ExtensibleEvents,
53+
}
54+
55+
impl RoomVersionFeatures {
56+
fn as_str(&self) -> &'static str {
57+
match self {
58+
RoomVersionFeatures::ExtensibleEvents => "org.matrix.msc3932.extensible_events",
59+
}
60+
}
3661
}
3762

3863
/// Allows running a set of push rules against a particular event.
@@ -121,7 +146,22 @@ impl PushRuleEvaluator {
121146
continue;
122147
}
123148

149+
let rule_id = &push_rule.rule_id().to_string();
150+
let extev_flag = &RoomVersionFeatures::ExtensibleEvents.as_str().to_string();
151+
let supports_extensible_events = self.room_version_feature_flags.contains(extev_flag);
152+
let safe_from_rver_condition = SAFE_EXTENSIBLE_EVENTS_RULE_IDS.contains(rule_id);
153+
let mut has_rver_condition = false;
154+
124155
for condition in push_rule.conditions.iter() {
156+
has_rver_condition = has_rver_condition
157+
|| match condition {
158+
Condition::Known(known) => match known {
159+
// per MSC3932, we just need *any* room version condition to match
160+
KnownCondition::RoomVersionSupports { feature: _ } => true,
161+
_ => false,
162+
},
163+
_ => false,
164+
};
125165
match self.match_condition(condition, user_id, display_name) {
126166
Ok(true) => {}
127167
Ok(false) => continue 'outer,
@@ -132,6 +172,13 @@ impl PushRuleEvaluator {
132172
}
133173
}
134174

175+
// MSC3932: Disable push rules in extensible event-supporting room versions if they
176+
// don't describe *any* MSC3931 room version condition, unless the rule is on the
177+
// safe list.
178+
if !has_rver_condition && !safe_from_rver_condition && supports_extensible_events {
179+
continue;
180+
}
181+
135182
let actions = push_rule
136183
.actions
137184
.iter()
@@ -394,3 +441,51 @@ fn push_rule_evaluator() {
394441
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
395442
assert_eq!(result.len(), 3);
396443
}
444+
445+
#[test]
446+
fn test_requires_room_version_supports_condition() {
447+
let mut flattened_keys = BTreeMap::new();
448+
flattened_keys.insert("content.body".to_string(), "foo bar bob hello".to_string());
449+
let flags = vec![RoomVersionFeatures::ExtensibleEvents.as_str().to_string()];
450+
let evaluator = PushRuleEvaluator::py_new(
451+
flattened_keys,
452+
10,
453+
Some(0),
454+
BTreeMap::new(),
455+
BTreeMap::new(),
456+
false,
457+
flags,
458+
true,
459+
)
460+
.unwrap();
461+
462+
// first test: are the master and contains_user_name rules excluded from the "requires room
463+
// version condition" check?
464+
let mut result = evaluator.run(
465+
&FilteredPushRules::default(),
466+
Some("@bob:example.org"),
467+
None,
468+
);
469+
assert_eq!(result.len(), 3);
470+
471+
// second test: if an appropriate push rule is in play, does it get handled?
472+
let custom_rule = PushRule {
473+
rule_id: Cow::from("global/underride/.org.example.extensible"),
474+
priority_class: 1, // underride
475+
conditions: Cow::from(vec![Condition::Known(
476+
KnownCondition::RoomVersionSupports {
477+
feature: Cow::from(RoomVersionFeatures::ExtensibleEvents.as_str().to_string()),
478+
},
479+
)]),
480+
actions: Cow::from(vec![Action::Notify]),
481+
default: false,
482+
default_enabled: true,
483+
};
484+
let rules = PushRules::new(vec![custom_rule]);
485+
result = evaluator.run(
486+
&FilteredPushRules::py_new(rules, BTreeMap::new(), true),
487+
None,
488+
None,
489+
);
490+
assert_eq!(result.len(), 1);
491+
}

synapse/api/room_versions.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ class RoomDisposition:
5151
UNSTABLE = "unstable"
5252

5353

54+
class PushRuleRoomFlag:
55+
"""Enum for listing possible MSC3931 room version feature flags, for push rules"""
56+
57+
# MSC3932: Room version supports MSC1767 Extensible Events.
58+
EXTENSIBLE_EVENTS = "org.matrix.msc3932.extensible_events"
59+
60+
5461
@attr.s(slots=True, frozen=True, auto_attribs=True)
5562
class RoomVersion:
5663
"""An object which describes the unique attributes of a room version."""
@@ -96,7 +103,7 @@ class RoomVersion:
96103
# is not enough to mark it "supported": the push rule evaluator also needs to
97104
# support the flag. Unknown flags are ignored by the evaluator, making conditions
98105
# fail if used.
99-
msc3931_push_features: List[str]
106+
msc3931_push_features: List[str] # values from PushRuleRoomFlag
100107

101108

102109
class RoomVersions:
@@ -347,6 +354,26 @@ class RoomVersions:
347354
msc3667_int_only_power_levels=False,
348355
msc3931_push_features=[],
349356
)
357+
MSC1767v10 = RoomVersion(
358+
# MSC1767 (Extensible Events) based on room version "10"
359+
"org.matrix.msc1767.10",
360+
RoomDisposition.UNSTABLE,
361+
EventFormatVersions.ROOM_V4_PLUS,
362+
StateResolutionVersions.V2,
363+
enforce_key_validity=True,
364+
special_case_aliases_auth=False,
365+
strict_canonicaljson=True,
366+
limit_notifications_power_levels=True,
367+
msc2176_redaction_rules=False,
368+
msc3083_join_rules=True,
369+
msc3375_redaction_rules=True,
370+
msc2403_knocking=True,
371+
msc2716_historical=False,
372+
msc2716_redactions=False,
373+
msc3787_knock_restricted_join_rule=True,
374+
msc3667_int_only_power_levels=True,
375+
msc3931_push_features=[PushRuleRoomFlag.EXTENSIBLE_EVENTS],
376+
)
350377

351378

352379
KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {

synapse/config/experimental.py

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import attr
1818

19+
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersions
1920
from synapse.config._base import Config
2021
from synapse.types import JsonDict
2122

@@ -131,3 +132,7 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
131132

132133
# MSC1767 and friends: Extensible Events
133134
self.msc1767_enabled: bool = experimental.get("msc1767_enabled", False)
135+
if self.msc1767_enabled:
136+
# Enable room version (and thus applicable push rules from MSC3931/3932)
137+
version_id = RoomVersions.MSC1767v10.identifier
138+
KNOWN_ROOM_VERSIONS[version_id] = RoomVersions.MSC1767v10

0 commit comments

Comments
 (0)