mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 00:31:24 +01:00
implement per-event filtering for ephemeral events in /sync
I've asked a few times for clarification on whether the `senders` field in the filter applies to userids mentioned in the typing/receipt ephemeral events, and never got a response. Synapse does not filter these userids by sender, so we're gonna go with that.
This commit is contained in:
parent
98d93da3a8
commit
d69b88566a
2 changed files with 48 additions and 33 deletions
|
|
@ -22,9 +22,12 @@ use ruma::{
|
||||||
uiaa::UiaaResponse,
|
uiaa::UiaaResponse,
|
||||||
},
|
},
|
||||||
events::{
|
events::{
|
||||||
|
receipt::ReceiptEventContent,
|
||||||
room::member::{MembershipState, RoomMemberEventContent},
|
room::member::{MembershipState, RoomMemberEventContent},
|
||||||
StateEventType, TimelineEventType,
|
typing::TypingEventContent,
|
||||||
|
StateEventType, StaticEventContent, TimelineEventType,
|
||||||
},
|
},
|
||||||
|
serde::Raw,
|
||||||
uint, DeviceId, EventId, JsOption, OwnedRoomId, OwnedUserId, RoomId, UInt,
|
uint, DeviceId, EventId, JsOption, OwnedRoomId, OwnedUserId, RoomId, UInt,
|
||||||
UserId,
|
UserId,
|
||||||
};
|
};
|
||||||
|
|
@ -933,39 +936,38 @@ async fn load_joined_room(
|
||||||
let room_events: Vec<_> =
|
let room_events: Vec<_> =
|
||||||
timeline_pdus.iter().map(|(_, pdu)| pdu.to_sync_room_event()).collect();
|
timeline_pdus.iter().map(|(_, pdu)| pdu.to_sync_room_event()).collect();
|
||||||
|
|
||||||
let edus = if filter.room.ephemeral.room_allowed(room_id) {
|
let mut edus = vec![];
|
||||||
let mut edus: Vec<_> = services()
|
if filter.room.ephemeral.room_allowed(room_id) {
|
||||||
.rooms
|
// We only filter on event type for ephemeral events because none of the
|
||||||
.edus
|
// other filter parameters apply to the specific ephemeral
|
||||||
.read_receipt
|
// events we're generating (m.room.receipt and m.room.typing).
|
||||||
.readreceipts_since(room_id, since)
|
// If we add fields to either of these events, or start
|
||||||
.filter_map(Result::ok)
|
// generating other event types in the future, we need to
|
||||||
.map(|(_, _, v)| v)
|
// reevaluate this.
|
||||||
.collect();
|
if filter.room.ephemeral.type_allowed(ReceiptEventContent::TYPE) {
|
||||||
|
edus.extend(
|
||||||
if services().rooms.edus.typing.last_typing_update(room_id).await?
|
services()
|
||||||
> since
|
.rooms
|
||||||
{
|
.edus
|
||||||
edus.push(
|
.read_receipt
|
||||||
serde_json::from_str(
|
.readreceipts_since(room_id, since)
|
||||||
&serde_json::to_string(
|
.filter_map(Result::ok)
|
||||||
&services()
|
.map(|(_, _, v)| v),
|
||||||
.rooms
|
|
||||||
.edus
|
|
||||||
.typing
|
|
||||||
.typings_all(room_id)
|
|
||||||
.await?,
|
|
||||||
)
|
|
||||||
.expect("event is valid, we just created it"),
|
|
||||||
)
|
|
||||||
.expect("event is valid, we just created it"),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
edus
|
if filter.room.ephemeral.type_allowed(TypingEventContent::TYPE)
|
||||||
} else {
|
&& services().rooms.edus.typing.last_typing_update(room_id).await?
|
||||||
vec![]
|
> since
|
||||||
};
|
{
|
||||||
|
let edu = services().rooms.edus.typing.typings_all(room_id).await?;
|
||||||
|
edus.push(
|
||||||
|
Raw::new(&edu)
|
||||||
|
.expect("event is valid, we just created it")
|
||||||
|
.cast(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let account_data_events = if filter.room.account_data.room_allowed(room_id)
|
let account_data_events = if filter.room.account_data.room_allowed(room_id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
//! top-level `filter.rooms.room`. Similarly, when a room is rejected for all
|
//! top-level `filter.rooms.room`. Similarly, when a room is rejected for all
|
||||||
//! events in a particular category, we can skip work generating events in that
|
//! events in a particular category, we can skip work generating events in that
|
||||||
//! category for the rejected room.
|
//! category for the rejected room.
|
||||||
|
//!
|
||||||
|
//! The second exception is ephemeral event types (`type`/`not_type` in
|
||||||
|
//! `filter.room.ephemeral`). For these, we can skip work generating events of a
|
||||||
|
//! particular type in `/sync` if it is rejected.
|
||||||
|
|
||||||
use std::{borrow::Cow, collections::HashSet, hash::Hash};
|
use std::{borrow::Cow, collections::HashSet, hash::Hash};
|
||||||
|
|
||||||
|
|
@ -258,6 +262,15 @@ impl CompiledRoomEventFilter<'_> {
|
||||||
self.rooms.allowed(room_id)
|
self.rooms.allowed(room_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if an event type is allowed by the `types` and
|
||||||
|
/// `not_types` fields.
|
||||||
|
///
|
||||||
|
/// This is mainly useful to skip work generating events for a particular
|
||||||
|
/// type, if that event type is always rejected by the filter.
|
||||||
|
pub(crate) fn type_allowed(&self, kind: &str) -> bool {
|
||||||
|
self.types.allowed(kind)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if a PDU event is allowed by the filter.
|
/// Returns `true` if a PDU event is allowed by the filter.
|
||||||
///
|
///
|
||||||
/// This tests against the `senders`, `not_senders`, `types`, `not_types`,
|
/// This tests against the `senders`, `not_senders`, `types`, `not_types`,
|
||||||
|
|
@ -269,7 +282,7 @@ impl CompiledRoomEventFilter<'_> {
|
||||||
/// [`CompiledRoomFilter::rooms`].
|
/// [`CompiledRoomFilter::rooms`].
|
||||||
pub(crate) fn pdu_event_allowed(&self, pdu: &PduEvent) -> bool {
|
pub(crate) fn pdu_event_allowed(&self, pdu: &PduEvent) -> bool {
|
||||||
self.senders.allowed(&pdu.sender)
|
self.senders.allowed(&pdu.sender)
|
||||||
&& self.types.allowed(&pdu.kind.to_string())
|
&& self.type_allowed(&pdu.kind.to_string())
|
||||||
&& self.allowed_by_url_filter(pdu)
|
&& self.allowed_by_url_filter(pdu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,7 +318,7 @@ impl CompiledRoomEventFilter<'_> {
|
||||||
|
|
||||||
allowed_by_url_filter
|
allowed_by_url_filter
|
||||||
&& self.senders.allowed(&event.sender)
|
&& self.senders.allowed(&event.sender)
|
||||||
&& self.types.allowed(&event.kind)
|
&& self.type_allowed(&event.kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor this as well?
|
// TODO: refactor this as well?
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue