mirror of
https://mau.dev/maunium/synapse.git
synced 2024-10-01 01:36:05 -04:00
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
This commit is contained in:
parent
3da6450327
commit
dd51828120
1
changelog.d/14521.feature
Normal file
1
changelog.d/14521.feature
Normal file
@ -0,0 +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).
|
@ -12,8 +12,10 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use crate::push::{PushRule, PushRules};
|
||||||
use anyhow::{Context, Error};
|
use anyhow::{Context, Error};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
@ -32,7 +34,30 @@ lazy_static! {
|
|||||||
|
|
||||||
/// Used to determine which MSC3931 room version feature flags are actually known to
|
/// Used to determine which MSC3931 room version feature flags are actually known to
|
||||||
/// the push evaluator.
|
/// the push evaluator.
|
||||||
static ref KNOWN_RVER_FLAGS: Vec<String> = vec![];
|
static ref KNOWN_RVER_FLAGS: Vec<String> = vec![
|
||||||
|
RoomVersionFeatures::ExtensibleEvents.as_str().to_string(),
|
||||||
|
];
|
||||||
|
|
||||||
|
/// The "safe" rule IDs which are not affected by MSC3932's behaviour (room versions which
|
||||||
|
/// declare Extensible Events support ultimately *disable* push rules which do not declare
|
||||||
|
/// *any* MSC3931 room_version_supports condition).
|
||||||
|
static ref SAFE_EXTENSIBLE_EVENTS_RULE_IDS: Vec<String> = vec![
|
||||||
|
"global/override/.m.rule.master".to_string(),
|
||||||
|
"global/override/.m.rule.roomnotif".to_string(),
|
||||||
|
"global/content/.m.rule.contains_user_name".to_string(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RoomVersionFeatures {
|
||||||
|
ExtensibleEvents,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RoomVersionFeatures {
|
||||||
|
fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
RoomVersionFeatures::ExtensibleEvents => "org.matrix.msc3932.extensible_events",
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allows running a set of push rules against a particular event.
|
/// Allows running a set of push rules against a particular event.
|
||||||
@ -121,7 +146,22 @@ impl PushRuleEvaluator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rule_id = &push_rule.rule_id().to_string();
|
||||||
|
let extev_flag = &RoomVersionFeatures::ExtensibleEvents.as_str().to_string();
|
||||||
|
let supports_extensible_events = self.room_version_feature_flags.contains(extev_flag);
|
||||||
|
let safe_from_rver_condition = SAFE_EXTENSIBLE_EVENTS_RULE_IDS.contains(rule_id);
|
||||||
|
let mut has_rver_condition = false;
|
||||||
|
|
||||||
for condition in push_rule.conditions.iter() {
|
for condition in push_rule.conditions.iter() {
|
||||||
|
has_rver_condition = has_rver_condition
|
||||||
|
|| match condition {
|
||||||
|
Condition::Known(known) => match known {
|
||||||
|
// per MSC3932, we just need *any* room version condition to match
|
||||||
|
KnownCondition::RoomVersionSupports { feature: _ } => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
match self.match_condition(condition, user_id, display_name) {
|
match self.match_condition(condition, user_id, display_name) {
|
||||||
Ok(true) => {}
|
Ok(true) => {}
|
||||||
Ok(false) => continue 'outer,
|
Ok(false) => continue 'outer,
|
||||||
@ -132,6 +172,13 @@ impl PushRuleEvaluator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MSC3932: Disable push rules in extensible event-supporting room versions if they
|
||||||
|
// don't describe *any* MSC3931 room version condition, unless the rule is on the
|
||||||
|
// safe list.
|
||||||
|
if !has_rver_condition && !safe_from_rver_condition && supports_extensible_events {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let actions = push_rule
|
let actions = push_rule
|
||||||
.actions
|
.actions
|
||||||
.iter()
|
.iter()
|
||||||
@ -394,3 +441,51 @@ fn push_rule_evaluator() {
|
|||||||
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
|
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_requires_room_version_supports_condition() {
|
||||||
|
let mut flattened_keys = BTreeMap::new();
|
||||||
|
flattened_keys.insert("content.body".to_string(), "foo bar bob hello".to_string());
|
||||||
|
let flags = vec![RoomVersionFeatures::ExtensibleEvents.as_str().to_string()];
|
||||||
|
let evaluator = PushRuleEvaluator::py_new(
|
||||||
|
flattened_keys,
|
||||||
|
10,
|
||||||
|
Some(0),
|
||||||
|
BTreeMap::new(),
|
||||||
|
BTreeMap::new(),
|
||||||
|
false,
|
||||||
|
flags,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// first test: are the master and contains_user_name rules excluded from the "requires room
|
||||||
|
// version condition" check?
|
||||||
|
let mut result = evaluator.run(
|
||||||
|
&FilteredPushRules::default(),
|
||||||
|
Some("@bob:example.org"),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert_eq!(result.len(), 3);
|
||||||
|
|
||||||
|
// second test: if an appropriate push rule is in play, does it get handled?
|
||||||
|
let custom_rule = PushRule {
|
||||||
|
rule_id: Cow::from("global/underride/.org.example.extensible"),
|
||||||
|
priority_class: 1, // underride
|
||||||
|
conditions: Cow::from(vec![Condition::Known(
|
||||||
|
KnownCondition::RoomVersionSupports {
|
||||||
|
feature: Cow::from(RoomVersionFeatures::ExtensibleEvents.as_str().to_string()),
|
||||||
|
},
|
||||||
|
)]),
|
||||||
|
actions: Cow::from(vec![Action::Notify]),
|
||||||
|
default: false,
|
||||||
|
default_enabled: true,
|
||||||
|
};
|
||||||
|
let rules = PushRules::new(vec![custom_rule]);
|
||||||
|
result = evaluator.run(
|
||||||
|
&FilteredPushRules::py_new(rules, BTreeMap::new(), true),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
assert_eq!(result.len(), 1);
|
||||||
|
}
|
||||||
|
@ -51,6 +51,13 @@ class RoomDisposition:
|
|||||||
UNSTABLE = "unstable"
|
UNSTABLE = "unstable"
|
||||||
|
|
||||||
|
|
||||||
|
class PushRuleRoomFlag:
|
||||||
|
"""Enum for listing possible MSC3931 room version feature flags, for push rules"""
|
||||||
|
|
||||||
|
# MSC3932: Room version supports MSC1767 Extensible Events.
|
||||||
|
EXTENSIBLE_EVENTS = "org.matrix.msc3932.extensible_events"
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
@attr.s(slots=True, frozen=True, auto_attribs=True)
|
||||||
class RoomVersion:
|
class RoomVersion:
|
||||||
"""An object which describes the unique attributes of a room version."""
|
"""An object which describes the unique attributes of a room version."""
|
||||||
@ -96,7 +103,7 @@ class RoomVersion:
|
|||||||
# is not enough to mark it "supported": the push rule evaluator also needs to
|
# is not enough to mark it "supported": the push rule evaluator also needs to
|
||||||
# support the flag. Unknown flags are ignored by the evaluator, making conditions
|
# support the flag. Unknown flags are ignored by the evaluator, making conditions
|
||||||
# fail if used.
|
# fail if used.
|
||||||
msc3931_push_features: List[str]
|
msc3931_push_features: List[str] # values from PushRuleRoomFlag
|
||||||
|
|
||||||
|
|
||||||
class RoomVersions:
|
class RoomVersions:
|
||||||
@ -347,6 +354,26 @@ class RoomVersions:
|
|||||||
msc3667_int_only_power_levels=False,
|
msc3667_int_only_power_levels=False,
|
||||||
msc3931_push_features=[],
|
msc3931_push_features=[],
|
||||||
)
|
)
|
||||||
|
MSC1767v10 = RoomVersion(
|
||||||
|
# MSC1767 (Extensible Events) based on room version "10"
|
||||||
|
"org.matrix.msc1767.10",
|
||||||
|
RoomDisposition.UNSTABLE,
|
||||||
|
EventFormatVersions.ROOM_V4_PLUS,
|
||||||
|
StateResolutionVersions.V2,
|
||||||
|
enforce_key_validity=True,
|
||||||
|
special_case_aliases_auth=False,
|
||||||
|
strict_canonicaljson=True,
|
||||||
|
limit_notifications_power_levels=True,
|
||||||
|
msc2176_redaction_rules=False,
|
||||||
|
msc3083_join_rules=True,
|
||||||
|
msc3375_redaction_rules=True,
|
||||||
|
msc2403_knocking=True,
|
||||||
|
msc2716_historical=False,
|
||||||
|
msc2716_redactions=False,
|
||||||
|
msc3787_knock_restricted_join_rule=True,
|
||||||
|
msc3667_int_only_power_levels=True,
|
||||||
|
msc3931_push_features=[PushRuleRoomFlag.EXTENSIBLE_EVENTS],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
||||||
|
@ -16,6 +16,7 @@ from typing import Any, Optional
|
|||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
|
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersions
|
||||||
from synapse.config._base import Config
|
from synapse.config._base import Config
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
|
|
||||||
@ -131,3 +132,7 @@ class ExperimentalConfig(Config):
|
|||||||
|
|
||||||
# MSC1767 and friends: Extensible Events
|
# MSC1767 and friends: Extensible Events
|
||||||
self.msc1767_enabled: bool = experimental.get("msc1767_enabled", False)
|
self.msc1767_enabled: bool = experimental.get("msc1767_enabled", False)
|
||||||
|
if self.msc1767_enabled:
|
||||||
|
# Enable room version (and thus applicable push rules from MSC3931/3932)
|
||||||
|
version_id = RoomVersions.MSC1767v10.identifier
|
||||||
|
KNOWN_ROOM_VERSIONS[version_id] = RoomVersions.MSC1767v10
|
||||||
|
Loading…
Reference in New Issue
Block a user