feat: add support for unstable-msc3931/3932 style push conditions parsing
This commit is contained in:
parent
89e06adecf
commit
9460702b00
@ -43,6 +43,8 @@ unstable-msc3552 = ["unstable-msc3551"]
|
||||
unstable-msc3553 = ["unstable-msc3552"]
|
||||
unstable-msc3554 = ["unstable-msc1767"]
|
||||
unstable-msc3783 = []
|
||||
unstable-msc3931 = []
|
||||
unstable-msc3932 = ["unstable-msc3931"]
|
||||
unstable-pdu = []
|
||||
unstable-sanitize = ["dep:html5ever", "dep:phf"]
|
||||
unstable-unspecified = []
|
||||
|
@ -33,6 +33,8 @@ mod condition;
|
||||
mod iter;
|
||||
mod predefined;
|
||||
|
||||
#[cfg(feature = "unstable-msc3932")]
|
||||
pub use self::condition::RoomVersionFeature;
|
||||
pub use self::{
|
||||
action::{Action, Tweak},
|
||||
condition::{
|
||||
@ -433,7 +435,33 @@ impl ConditionalPushRule {
|
||||
/// * `event` - The flattened JSON representation of a room message event.
|
||||
/// * `context` - The context of the room at the time of the event.
|
||||
pub fn applies(&self, event: &FlattenedJson, context: &PushConditionRoomCtx) -> bool {
|
||||
self.enabled && self.conditions.iter().all(|cond| cond.applies(event, context))
|
||||
if !self.enabled {
|
||||
return false;
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc3932")]
|
||||
{
|
||||
// These 3 rules always apply.
|
||||
if self.rule_id != PredefinedOverrideRuleId::Master.as_ref()
|
||||
&& self.rule_id != PredefinedOverrideRuleId::RoomNotif.as_ref()
|
||||
&& self.rule_id != PredefinedOverrideRuleId::ContainsDisplayName.as_ref()
|
||||
{
|
||||
// Push rules which don't specify a `room_version_supports` condition are assumed
|
||||
// to not support extensible events and are therefore expected to be treated as
|
||||
// disabled when a room version does support extensible events.
|
||||
let room_supports_ext_ev =
|
||||
context.supported_features.contains(&RoomVersionFeature::ExtensibleEvents);
|
||||
let rule_has_room_version_supports = self.conditions.iter().any(|condition| {
|
||||
matches!(condition, PushCondition::RoomVersionSupports { .. })
|
||||
});
|
||||
|
||||
if room_supports_ext_ev && !rule_has_room_version_supports {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.conditions.iter().all(|cond| cond.applies(event, context))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1337,6 +1365,8 @@ mod tests {
|
||||
users_power_levels: BTreeMap::new(),
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
supported_features: Default::default(),
|
||||
};
|
||||
|
||||
let context_public_room = &PushConditionRoomCtx {
|
||||
@ -1347,6 +1377,8 @@ mod tests {
|
||||
users_power_levels: BTreeMap::new(),
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
supported_features: Default::default(),
|
||||
};
|
||||
|
||||
let message = serde_json::from_str::<Raw<JsonValue>>(
|
||||
@ -1438,6 +1470,8 @@ mod tests {
|
||||
users_power_levels: BTreeMap::new(),
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
supported_features: Default::default(),
|
||||
};
|
||||
|
||||
let message = serde_json::from_str::<Raw<JsonValue>>(
|
||||
|
@ -2,17 +2,60 @@ use std::{collections::BTreeMap, ops::RangeBounds, str::FromStr};
|
||||
|
||||
use js_int::{Int, UInt};
|
||||
use regex::Regex;
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
use ruma_macros::StringEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{to_value as to_json_value, value::Value as JsonValue};
|
||||
use tracing::{instrument, warn};
|
||||
use wildmatch::WildMatch;
|
||||
|
||||
use crate::{power_levels::NotificationPowerLevels, serde::Raw, OwnedRoomId, OwnedUserId, UserId};
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
use crate::{PrivOwnedStr, RoomVersionId};
|
||||
|
||||
mod room_member_count_is;
|
||||
|
||||
pub use room_member_count_is::{ComparisonOperator, RoomMemberCountIs};
|
||||
|
||||
/// Features supported by room versions.
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, StringEnum)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub enum RoomVersionFeature {
|
||||
/// m.extensible_events
|
||||
///
|
||||
/// The room supports [extensible events].
|
||||
///
|
||||
/// [extensible events]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767
|
||||
#[cfg(feature = "unstable-msc3932")]
|
||||
#[ruma_enum(rename = "org.matrix.msc3932.extensible_events")]
|
||||
ExtensibleEvents,
|
||||
|
||||
#[doc(hidden)]
|
||||
_Custom(PrivOwnedStr),
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
impl RoomVersionFeature {
|
||||
/// Get the default features for the given room version.
|
||||
pub fn list_for_room_version(version: &RoomVersionId) -> Vec<Self> {
|
||||
match version {
|
||||
RoomVersionId::V1
|
||||
| RoomVersionId::V2
|
||||
| RoomVersionId::V3
|
||||
| RoomVersionId::V4
|
||||
| RoomVersionId::V5
|
||||
| RoomVersionId::V6
|
||||
| RoomVersionId::V7
|
||||
| RoomVersionId::V8
|
||||
| RoomVersionId::V9
|
||||
| RoomVersionId::V10
|
||||
| RoomVersionId::_Custom(_) => vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A condition that must apply for an associated push rule's action to be taken.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
@ -49,6 +92,14 @@ pub enum PushCondition {
|
||||
/// `content`.
|
||||
key: String,
|
||||
},
|
||||
|
||||
/// Apply the rule only to rooms that support a given feature.
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
#[serde(rename = "org.matrix.msc3931.room_version_supports")]
|
||||
RoomVersionSupports {
|
||||
/// The feature the room must support for the push rule to apply.
|
||||
feature: RoomVersionFeature,
|
||||
},
|
||||
}
|
||||
|
||||
pub(super) fn check_event_match(
|
||||
@ -110,6 +161,13 @@ impl PushCondition {
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
Self::RoomVersionSupports { feature } => match feature {
|
||||
RoomVersionFeature::ExtensibleEvents => {
|
||||
context.supported_features.contains(&RoomVersionFeature::ExtensibleEvents)
|
||||
}
|
||||
RoomVersionFeature::_Custom(_) => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,6 +196,10 @@ pub struct PushConditionRoomCtx {
|
||||
|
||||
/// The notification power levels of the room.
|
||||
pub notification_power_levels: NotificationPowerLevels,
|
||||
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
/// The list of features this room's version or the room itself supports.
|
||||
pub supported_features: Vec<RoomVersionFeature>,
|
||||
}
|
||||
|
||||
/// Additional functions for character matching.
|
||||
@ -585,6 +647,8 @@ mod tests {
|
||||
users_power_levels,
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
#[cfg(feature = "unstable-msc3931")]
|
||||
supported_features: Default::default(),
|
||||
};
|
||||
|
||||
let first_event_raw = serde_json::from_str::<Raw<JsonValue>>(
|
||||
@ -658,6 +722,56 @@ mod tests {
|
||||
assert!(sender_notification_permission.applies(&second_event, &context));
|
||||
}
|
||||
|
||||
#[cfg(feature = "unstable-msc3932")]
|
||||
#[test]
|
||||
fn conditions_apply_to_events_in_room_with_feature() {
|
||||
let first_sender = user_id!("@worthy_whale:server.name").to_owned();
|
||||
|
||||
let mut users_power_levels = BTreeMap::new();
|
||||
users_power_levels.insert(first_sender, int!(25));
|
||||
|
||||
let context_matching = PushConditionRoomCtx {
|
||||
room_id: room_id!("!room:server.name").to_owned(),
|
||||
member_count: uint!(3),
|
||||
user_id: user_id!("@gorilla:server.name").to_owned(),
|
||||
user_display_name: "Groovy Gorilla".into(),
|
||||
users_power_levels: users_power_levels.clone(),
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
supported_features: vec![super::RoomVersionFeature::ExtensibleEvents],
|
||||
};
|
||||
|
||||
let context_not_matching = PushConditionRoomCtx {
|
||||
room_id: room_id!("!room:server.name").to_owned(),
|
||||
member_count: uint!(3),
|
||||
user_id: user_id!("@gorilla:server.name").to_owned(),
|
||||
user_display_name: "Groovy Gorilla".into(),
|
||||
users_power_levels,
|
||||
default_power_level: int!(50),
|
||||
notification_power_levels: NotificationPowerLevels { room: int!(50) },
|
||||
supported_features: vec![],
|
||||
};
|
||||
|
||||
let simple_event_raw = serde_json::from_str::<Raw<JsonValue>>(
|
||||
r#"{
|
||||
"sender": "@worthy_whale:server.name",
|
||||
"content": {
|
||||
"msgtype": "org.matrix.msc3932.extensible_events",
|
||||
"body": "@room Give a warm welcome to Groovy Gorilla"
|
||||
}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let simple_event = FlattenedJson::from_raw(&simple_event_raw);
|
||||
|
||||
let room_version_condition = PushCondition::RoomVersionSupports {
|
||||
feature: super::RoomVersionFeature::ExtensibleEvents,
|
||||
};
|
||||
|
||||
assert!(room_version_condition.applies(&simple_event, &context_matching));
|
||||
assert!(!room_version_condition.applies(&simple_event, &context_not_matching));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flattened_json_values() {
|
||||
let raw = serde_json::from_str::<Raw<JsonValue>>(
|
||||
|
@ -155,6 +155,8 @@ unstable-msc3575 = ["ruma-client-api?/unstable-msc3575"]
|
||||
unstable-msc3618 = ["ruma-federation-api?/unstable-msc3618"]
|
||||
unstable-msc3723 = ["ruma-federation-api?/unstable-msc3723"]
|
||||
unstable-msc3783 = ["ruma-common/unstable-msc3783"]
|
||||
unstable-msc3931 = ["ruma-common/unstable-msc3931"]
|
||||
unstable-msc3932 = ["ruma-common/unstable-msc3932"]
|
||||
unstable-pdu = ["ruma-common/unstable-pdu"]
|
||||
unstable-sanitize = ["ruma-common/unstable-sanitize"]
|
||||
unstable-unspecified = [
|
||||
@ -193,6 +195,7 @@ __ci = [
|
||||
"unstable-msc3618",
|
||||
"unstable-msc3723",
|
||||
"unstable-msc3783",
|
||||
"unstable-msc3932",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
|
Loading…
x
Reference in New Issue
Block a user