mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 00:31:24 +01:00
implement per-event state filtering for invited rooms on /sync
This one is a little weird, because the stripped invite state events are not deserialized.
This commit is contained in:
parent
4c9728cbad
commit
b85110a292
2 changed files with 47 additions and 3 deletions
|
|
@ -262,9 +262,14 @@ pub(crate) async fn sync_events_route(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let state_events = invite_state_events
|
||||||
|
.into_iter()
|
||||||
|
.filter(|event| compiled_filter.room.state.raw_event_allowed(event))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let invited_room = InvitedRoom {
|
let invited_room = InvitedRoom {
|
||||||
invite_state: InviteState {
|
invite_state: InviteState {
|
||||||
events: invite_state_events,
|
events: state_events,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if !invited_room.is_empty() {
|
if !invited_room.is_empty() {
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,18 @@
|
||||||
//! 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.
|
||||||
|
|
||||||
use std::{collections::HashSet, hash::Hash};
|
use std::{borrow::Cow, collections::HashSet, hash::Hash};
|
||||||
|
|
||||||
use regex::RegexSet;
|
use regex::RegexSet;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::filter::{
|
api::client::filter::{
|
||||||
FilterDefinition, RoomEventFilter, RoomFilter, UrlFilter,
|
FilterDefinition, RoomEventFilter, RoomFilter, UrlFilter,
|
||||||
},
|
},
|
||||||
RoomId, UserId,
|
serde::Raw,
|
||||||
|
OwnedUserId, RoomId, UserId,
|
||||||
};
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
use crate::{Error, PduEvent};
|
use crate::{Error, PduEvent};
|
||||||
|
|
||||||
|
|
@ -270,6 +273,42 @@ impl CompiledRoomEventFilter<'_> {
|
||||||
&& self.allowed_by_url_filter(pdu)
|
&& self.allowed_by_url_filter(pdu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Similar to [`CompiledRoomEventFilter::pdu_event_allowed`] but takes raw
|
||||||
|
/// JSON.
|
||||||
|
pub(crate) fn raw_event_allowed<Ev>(&self, event: &Raw<Ev>) -> bool {
|
||||||
|
// We need to deserialize some of the fields from the raw json, but
|
||||||
|
// don't need all of them. Fully deserializing to a ruma event type
|
||||||
|
// would involve a lot extra copying and validation.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct LimitedEvent<'a> {
|
||||||
|
sender: OwnedUserId,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
kind: Cow<'a, str>,
|
||||||
|
url: Option<Cow<'a, str>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let event = match event.deserialize_as::<LimitedEvent<'_>>() {
|
||||||
|
Ok(event) => event,
|
||||||
|
Err(e) => {
|
||||||
|
// TODO: maybe rephrase this error, or propagate it to the
|
||||||
|
// caller
|
||||||
|
error!("invalid event in database: {e}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let allowed_by_url_filter = match self.url_filter {
|
||||||
|
None => true,
|
||||||
|
Some(UrlFilter::EventsWithoutUrl) => event.url.is_none(),
|
||||||
|
Some(UrlFilter::EventsWithUrl) => event.url.is_some(),
|
||||||
|
};
|
||||||
|
|
||||||
|
allowed_by_url_filter
|
||||||
|
&& self.senders.allowed(&event.sender)
|
||||||
|
&& self.types.allowed(&event.kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: refactor this as well?
|
||||||
fn allowed_by_url_filter(&self, pdu: &PduEvent) -> bool {
|
fn allowed_by_url_filter(&self, pdu: &PduEvent) -> bool {
|
||||||
let Some(filter) = self.url_filter else {
|
let Some(filter) = self.url_filter else {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue