mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 08:41:24 +01:00
implement global account_data filtering in /sync
TODO docs on raw_event_allowed, and figure out how we want to organize it with CompiledRoomEventFilter::raw_event_allowed
This commit is contained in:
parent
c3cf97df7a
commit
7a0b8c986f
2 changed files with 37 additions and 0 deletions
|
|
@ -346,6 +346,9 @@ pub(crate) async fn sync_events_route(
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
|
.filter(|event| {
|
||||||
|
compiled_filter.account_data.raw_event_allowed(event)
|
||||||
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
device_lists: DeviceLists {
|
device_lists: DeviceLists {
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ impl WildcardAllowDenyList {
|
||||||
/// `types`/`not_types`, this is a [`WildcardAllowDenyList`], because the type
|
/// `types`/`not_types`, this is a [`WildcardAllowDenyList`], because the type
|
||||||
/// filter fields support `'*'` wildcards.
|
/// filter fields support `'*'` wildcards.
|
||||||
pub(crate) struct CompiledFilterDefinition<'a> {
|
pub(crate) struct CompiledFilterDefinition<'a> {
|
||||||
|
pub(crate) account_data: CompiledFilter<'a>,
|
||||||
pub(crate) room: CompiledRoomFilter<'a>,
|
pub(crate) room: CompiledRoomFilter<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,6 +189,7 @@ impl<'a> TryFrom<&'a FilterDefinition> for CompiledFilterDefinition<'a> {
|
||||||
source: &'a FilterDefinition,
|
source: &'a FilterDefinition,
|
||||||
) -> Result<CompiledFilterDefinition<'a>, Error> {
|
) -> Result<CompiledFilterDefinition<'a>, Error> {
|
||||||
Ok(CompiledFilterDefinition {
|
Ok(CompiledFilterDefinition {
|
||||||
|
account_data: (&source.account_data).try_into()?,
|
||||||
room: (&source.room).try_into()?,
|
room: (&source.room).try_into()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +240,38 @@ impl<'a> TryFrom<&'a RoomEventFilter> for CompiledRoomEventFilter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl CompiledFilter<'_> {
|
||||||
|
// TODO: docs
|
||||||
|
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: Option<OwnedUserId>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
kind: 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 sender_allowed = match &event.sender {
|
||||||
|
Some(sender) => self.senders.allowed(sender),
|
||||||
|
// sender allowlist means we reject events without a sender
|
||||||
|
None => matches!(self.senders, AllowDenyList::Deny(_)),
|
||||||
|
};
|
||||||
|
sender_allowed && self.types.allowed(&event.kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CompiledRoomFilter<'_> {
|
impl CompiledRoomFilter<'_> {
|
||||||
/// Returns the top-level [`AllowDenyList`] for rooms (`rooms`/`not_rooms`
|
/// Returns the top-level [`AllowDenyList`] for rooms (`rooms`/`not_rooms`
|
||||||
/// in `filter.room`).
|
/// in `filter.room`).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue