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

Commit 3da6450

Browse files
authored
Initial support for MSC3931: Room version push rule feature flags (#14520)
* Add support for MSC3931: Room Version Supports push rule condition * Create experimental flag for future work, and use it to gate MSC3931 * Changelog entry
1 parent 8f10c8b commit 3da6450

File tree

8 files changed

+76
-1
lines changed

8 files changed

+76
-1
lines changed

changelog.d/14520.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

+26
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ use super::{
2929
lazy_static! {
3030
/// Used to parse the `is` clause in the room member count condition.
3131
static ref INEQUALITY_EXPR: Regex = Regex::new(r"^([=<>]*)([0-9]+)$").expect("valid regex");
32+
33+
/// Used to determine which MSC3931 room version feature flags are actually known to
34+
/// the push evaluator.
35+
static ref KNOWN_RVER_FLAGS: Vec<String> = vec![];
3236
}
3337

3438
/// Allows running a set of push rules against a particular event.
@@ -57,6 +61,13 @@ pub struct PushRuleEvaluator {
5761

5862
/// If msc3664, push rules for related events, is enabled.
5963
related_event_match_enabled: bool,
64+
65+
/// If MSC3931 is applicable, the feature flags for the room version.
66+
room_version_feature_flags: Vec<String>,
67+
68+
/// If MSC3931 (room version feature flags) is enabled. Usually controlled by the same
69+
/// flag as MSC1767 (extensible events core).
70+
msc3931_enabled: bool,
6071
}
6172

6273
#[pymethods]
@@ -70,6 +81,8 @@ impl PushRuleEvaluator {
7081
notification_power_levels: BTreeMap<String, i64>,
7182
related_events_flattened: BTreeMap<String, BTreeMap<String, String>>,
7283
related_event_match_enabled: bool,
84+
room_version_feature_flags: Vec<String>,
85+
msc3931_enabled: bool,
7386
) -> Result<Self, Error> {
7487
let body = flattened_keys
7588
.get("content.body")
@@ -84,6 +97,8 @@ impl PushRuleEvaluator {
8497
sender_power_level,
8598
related_events_flattened,
8699
related_event_match_enabled,
100+
room_version_feature_flags,
101+
msc3931_enabled,
87102
})
88103
}
89104

@@ -204,6 +219,15 @@ impl PushRuleEvaluator {
204219
false
205220
}
206221
}
222+
KnownCondition::RoomVersionSupports { feature } => {
223+
if !self.msc3931_enabled {
224+
false
225+
} else {
226+
let flag = feature.to_string();
227+
KNOWN_RVER_FLAGS.contains(&flag)
228+
&& self.room_version_feature_flags.contains(&flag)
229+
}
230+
}
207231
};
208232

209233
Ok(result)
@@ -362,6 +386,8 @@ fn push_rule_evaluator() {
362386
BTreeMap::new(),
363387
BTreeMap::new(),
364388
true,
389+
vec![],
390+
true,
365391
)
366392
.unwrap();
367393

rust/src/push/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ pub enum KnownCondition {
277277
SenderNotificationPermission {
278278
key: Cow<'static, str>,
279279
},
280+
#[serde(rename = "org.matrix.msc3931.room_version_supports")]
281+
RoomVersionSupports {
282+
feature: Cow<'static, str>,
283+
},
280284
}
281285

282286
impl IntoPy<PyObject> for Condition {
@@ -491,6 +495,18 @@ fn test_deserialize_unstable_msc3664_condition() {
491495
));
492496
}
493497

498+
#[test]
499+
fn test_deserialize_unstable_msc3931_condition() {
500+
let json =
501+
r#"{"kind":"org.matrix.msc3931.room_version_supports","feature":"org.example.feature"}"#;
502+
503+
let condition: Condition = serde_json::from_str(json).unwrap();
504+
assert!(matches!(
505+
condition,
506+
Condition::Known(KnownCondition::RoomVersionSupports { feature: _ })
507+
));
508+
}
509+
494510
#[test]
495511
fn test_deserialize_custom_condition() {
496512
let json = r#"{"kind":"custom_tag"}"#;

stubs/synapse/synapse_rust/push.pyi

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class PushRuleEvaluator:
4141
notification_power_levels: Mapping[str, int],
4242
related_events_flattened: Mapping[str, Mapping[str, str]],
4343
related_event_match_enabled: bool,
44+
room_version_feature_flags: list[str],
45+
msc3931_enabled: bool,
4446
): ...
4547
def run(
4648
self,

synapse/api/room_versions.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Callable, Dict, Optional
15+
from typing import Callable, Dict, List, Optional
1616

1717
import attr
1818

@@ -91,6 +91,12 @@ class RoomVersion:
9191
msc3787_knock_restricted_join_rule: bool
9292
# MSC3667: Enforce integer power levels
9393
msc3667_int_only_power_levels: bool
94+
# MSC3931: Adds a push rule condition for "room version feature flags", making
95+
# some push rules room version dependent. Note that adding a flag to this list
96+
# is not enough to mark it "supported": the push rule evaluator also needs to
97+
# support the flag. Unknown flags are ignored by the evaluator, making conditions
98+
# fail if used.
99+
msc3931_push_features: List[str]
94100

95101

96102
class RoomVersions:
@@ -111,6 +117,7 @@ class RoomVersions:
111117
msc2716_redactions=False,
112118
msc3787_knock_restricted_join_rule=False,
113119
msc3667_int_only_power_levels=False,
120+
msc3931_push_features=[],
114121
)
115122
V2 = RoomVersion(
116123
"2",
@@ -129,6 +136,7 @@ class RoomVersions:
129136
msc2716_redactions=False,
130137
msc3787_knock_restricted_join_rule=False,
131138
msc3667_int_only_power_levels=False,
139+
msc3931_push_features=[],
132140
)
133141
V3 = RoomVersion(
134142
"3",
@@ -147,6 +155,7 @@ class RoomVersions:
147155
msc2716_redactions=False,
148156
msc3787_knock_restricted_join_rule=False,
149157
msc3667_int_only_power_levels=False,
158+
msc3931_push_features=[],
150159
)
151160
V4 = RoomVersion(
152161
"4",
@@ -165,6 +174,7 @@ class RoomVersions:
165174
msc2716_redactions=False,
166175
msc3787_knock_restricted_join_rule=False,
167176
msc3667_int_only_power_levels=False,
177+
msc3931_push_features=[],
168178
)
169179
V5 = RoomVersion(
170180
"5",
@@ -183,6 +193,7 @@ class RoomVersions:
183193
msc2716_redactions=False,
184194
msc3787_knock_restricted_join_rule=False,
185195
msc3667_int_only_power_levels=False,
196+
msc3931_push_features=[],
186197
)
187198
V6 = RoomVersion(
188199
"6",
@@ -201,6 +212,7 @@ class RoomVersions:
201212
msc2716_redactions=False,
202213
msc3787_knock_restricted_join_rule=False,
203214
msc3667_int_only_power_levels=False,
215+
msc3931_push_features=[],
204216
)
205217
MSC2176 = RoomVersion(
206218
"org.matrix.msc2176",
@@ -219,6 +231,7 @@ class RoomVersions:
219231
msc2716_redactions=False,
220232
msc3787_knock_restricted_join_rule=False,
221233
msc3667_int_only_power_levels=False,
234+
msc3931_push_features=[],
222235
)
223236
V7 = RoomVersion(
224237
"7",
@@ -237,6 +250,7 @@ class RoomVersions:
237250
msc2716_redactions=False,
238251
msc3787_knock_restricted_join_rule=False,
239252
msc3667_int_only_power_levels=False,
253+
msc3931_push_features=[],
240254
)
241255
V8 = RoomVersion(
242256
"8",
@@ -255,6 +269,7 @@ class RoomVersions:
255269
msc2716_redactions=False,
256270
msc3787_knock_restricted_join_rule=False,
257271
msc3667_int_only_power_levels=False,
272+
msc3931_push_features=[],
258273
)
259274
V9 = RoomVersion(
260275
"9",
@@ -273,6 +288,7 @@ class RoomVersions:
273288
msc2716_redactions=False,
274289
msc3787_knock_restricted_join_rule=False,
275290
msc3667_int_only_power_levels=False,
291+
msc3931_push_features=[],
276292
)
277293
MSC3787 = RoomVersion(
278294
"org.matrix.msc3787",
@@ -291,6 +307,7 @@ class RoomVersions:
291307
msc2716_redactions=False,
292308
msc3787_knock_restricted_join_rule=True,
293309
msc3667_int_only_power_levels=False,
310+
msc3931_push_features=[],
294311
)
295312
V10 = RoomVersion(
296313
"10",
@@ -309,6 +326,7 @@ class RoomVersions:
309326
msc2716_redactions=False,
310327
msc3787_knock_restricted_join_rule=True,
311328
msc3667_int_only_power_levels=True,
329+
msc3931_push_features=[],
312330
)
313331
MSC2716v4 = RoomVersion(
314332
"org.matrix.msc2716v4",
@@ -327,6 +345,7 @@ class RoomVersions:
327345
msc2716_redactions=True,
328346
msc3787_knock_restricted_join_rule=False,
329347
msc3667_int_only_power_levels=False,
348+
msc3931_push_features=[],
330349
)
331350

332351

synapse/config/experimental.py

+3
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,6 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
128128

129129
# MSC3912: Relation-based redactions.
130130
self.msc3912_enabled: bool = experimental.get("msc3912_enabled", False)
131+
132+
# MSC1767 and friends: Extensible Events
133+
self.msc1767_enabled: bool = experimental.get("msc1767_enabled", False)

synapse/push/bulk_push_rule_evaluator.py

+6
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,19 @@ async def _action_for_event_by_user(
338338
for user_id, level in notification_levels.items():
339339
notification_levels[user_id] = int(level)
340340

341+
room_version_features = event.room_version.msc3931_push_features
342+
if not room_version_features:
343+
room_version_features = []
344+
341345
evaluator = PushRuleEvaluator(
342346
_flatten_dict(event),
343347
room_member_count,
344348
sender_power_level,
345349
notification_levels,
346350
related_events,
347351
self._related_event_match_enabled,
352+
room_version_features,
353+
self.hs.config.experimental.msc1767_enabled, # MSC3931 flag
348354
)
349355

350356
users = rules_by_user.keys()

tests/push/test_push_rule_evaluator.py

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ def _get_evaluator(
6262
power_levels.get("notifications", {}),
6363
{} if related_events is None else related_events,
6464
True,
65+
event.room_version.msc3931_push_features,
66+
True,
6567
)
6668

6769
def test_display_name(self) -> None:

0 commit comments

Comments
 (0)