mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-19 00:31:24 +01:00
implement contains_url filter for /message
The plan is to move all of the per-event checks into the pdu_event_allowed function. TODO: split the `visibility_filter` function into it's own commit. I think this one was inherited from an earlier conduwuit commit.
This commit is contained in:
parent
2bcd357db2
commit
0e2694a6c4
2 changed files with 50 additions and 22 deletions
|
|
@ -9,14 +9,14 @@ use ruma::{
|
||||||
message::{get_message_events, send_message_event},
|
message::{get_message_events, send_message_event},
|
||||||
},
|
},
|
||||||
events::{StateEventType, TimelineEventType},
|
events::{StateEventType, TimelineEventType},
|
||||||
uint, UInt,
|
uint, RoomId, UInt, UserId,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
service::{pdu::PduBuilder, rooms::timeline::PduCount},
|
service::{pdu::PduBuilder, rooms::timeline::PduCount},
|
||||||
services, utils,
|
services, utils,
|
||||||
utils::filter::{load_limit, CompiledRoomEventFilter},
|
utils::filter::{load_limit, CompiledRoomEventFilter},
|
||||||
Ar, Error, Ra, Result,
|
Ar, Error, PduEvent, Ra, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// # `PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}`
|
/// # `PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}`
|
||||||
|
|
@ -197,15 +197,8 @@ pub(crate) async fn get_message_events_route(
|
||||||
.take(load_limit(limit))
|
.take(load_limit(limit))
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.filter(|(_, pdu)| {
|
.filter(|(_, pdu)| {
|
||||||
services()
|
filter.pdu_event_allowed(pdu)
|
||||||
.rooms
|
&& visibility_filter(pdu, sender_user, &body.room_id)
|
||||||
.state_accessor
|
|
||||||
.user_can_see_event(
|
|
||||||
sender_user,
|
|
||||||
&body.room_id,
|
|
||||||
&pdu.event_id,
|
|
||||||
)
|
|
||||||
.unwrap_or(false)
|
|
||||||
})
|
})
|
||||||
.take_while(|&(k, _)| Some(k) != to)
|
.take_while(|&(k, _)| Some(k) != to)
|
||||||
.take(limit)
|
.take(limit)
|
||||||
|
|
@ -254,15 +247,8 @@ pub(crate) async fn get_message_events_route(
|
||||||
.take(load_limit(limit))
|
.take(load_limit(limit))
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.filter(|(_, pdu)| {
|
.filter(|(_, pdu)| {
|
||||||
services()
|
filter.pdu_event_allowed(pdu)
|
||||||
.rooms
|
&& visibility_filter(pdu, sender_user, &body.room_id)
|
||||||
.state_accessor
|
|
||||||
.user_can_see_event(
|
|
||||||
sender_user,
|
|
||||||
&body.room_id,
|
|
||||||
&pdu.event_id,
|
|
||||||
)
|
|
||||||
.unwrap_or(false)
|
|
||||||
})
|
})
|
||||||
.take_while(|&(k, _)| Some(k) != to)
|
.take_while(|&(k, _)| Some(k) != to)
|
||||||
.take(limit)
|
.take(limit)
|
||||||
|
|
@ -331,3 +317,15 @@ pub(crate) async fn get_message_events_route(
|
||||||
|
|
||||||
Ok(Ra(resp))
|
Ok(Ra(resp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visibility_filter(
|
||||||
|
pdu: &PduEvent,
|
||||||
|
user_id: &UserId,
|
||||||
|
room_id: &RoomId,
|
||||||
|
) -> bool {
|
||||||
|
services()
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.user_can_see_event(user_id, room_id, &pdu.event_id)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,12 @@
|
||||||
|
|
||||||
use std::{collections::HashSet, hash::Hash};
|
use std::{collections::HashSet, hash::Hash};
|
||||||
|
|
||||||
use ruma::{api::client::filter::RoomEventFilter, RoomId};
|
use ruma::{
|
||||||
|
api::client::filter::{RoomEventFilter, UrlFilter},
|
||||||
|
RoomId,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::Error;
|
use crate::{Error, PduEvent};
|
||||||
|
|
||||||
// 'DoS' is not a type
|
// 'DoS' is not a type
|
||||||
#[allow(clippy::doc_markdown)]
|
#[allow(clippy::doc_markdown)]
|
||||||
|
|
@ -82,6 +85,7 @@ impl<'a, T: ?Sized + Hash + PartialEq + Eq> AllowDenyList<'a, T> {
|
||||||
|
|
||||||
pub(crate) struct CompiledRoomEventFilter<'a> {
|
pub(crate) struct CompiledRoomEventFilter<'a> {
|
||||||
rooms: AllowDenyList<'a, RoomId>,
|
rooms: AllowDenyList<'a, RoomId>,
|
||||||
|
url_filter: Option<UrlFilter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a RoomEventFilter> for CompiledRoomEventFilter<'a> {
|
impl<'a> TryFrom<&'a RoomEventFilter> for CompiledRoomEventFilter<'a> {
|
||||||
|
|
@ -95,6 +99,7 @@ impl<'a> TryFrom<&'a RoomEventFilter> for CompiledRoomEventFilter<'a> {
|
||||||
source.rooms.as_deref(),
|
source.rooms.as_deref(),
|
||||||
&source.not_rooms,
|
&source.not_rooms,
|
||||||
),
|
),
|
||||||
|
url_filter: source.url_filter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,4 +115,29 @@ impl CompiledRoomEventFilter<'_> {
|
||||||
pub(crate) fn room_allowed(&self, room_id: &RoomId) -> bool {
|
pub(crate) fn room_allowed(&self, room_id: &RoomId) -> bool {
|
||||||
self.rooms.allowed(room_id)
|
self.rooms.allowed(room_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a PDU event is allowed by the filter.
|
||||||
|
///
|
||||||
|
/// This tests against the `url_filter` field.
|
||||||
|
///
|
||||||
|
/// This does *not* check whether the event's room is allowed. It is
|
||||||
|
/// expected that callers have already filtered out rejected rooms using
|
||||||
|
/// [`CompiledRoomEventFilter::room_allowed`] and
|
||||||
|
/// [`CompiledRoomFilter::rooms`].
|
||||||
|
pub(crate) fn pdu_event_allowed(&self, pdu: &PduEvent) -> bool {
|
||||||
|
self.allowed_by_url_filter(pdu)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allowed_by_url_filter(&self, pdu: &PduEvent) -> bool {
|
||||||
|
let Some(filter) = self.url_filter else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// TODO: is this unwrap okay?
|
||||||
|
let content: serde_json::Value =
|
||||||
|
serde_json::from_str(pdu.content.get()).unwrap();
|
||||||
|
match filter {
|
||||||
|
UrlFilter::EventsWithoutUrl => !content["url"].is_string(),
|
||||||
|
UrlFilter::EventsWithUrl => content["url"].is_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue