From ebb71b7d7c5c48fce9430309e19ce3dd05fd76a3 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 5 Apr 2024 06:34:56 -0700 Subject: [PATCH] add contains_url filter to /messages; also split out visibility filter. Signed-off-by: Jason Volk --- src/api/client_server/message.rs | 49 ++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/api/client_server/message.rs b/src/api/client_server/message.rs index a2399ac7..765dd595 100644 --- a/src/api/client_server/message.rs +++ b/src/api/client_server/message.rs @@ -6,15 +6,17 @@ use std::{ use ruma::{ api::client::{ error::ErrorKind, + filter::{RoomEventFilter, UrlFilter}, message::{get_message_events, send_message_event}, }, events::{MessageLikeEventType, StateEventType}, + RoomId, UserId, }; -use serde_json::from_str; +use serde_json::{from_str, Value}; use crate::{ service::{pdu::PduBuilder, rooms::timeline::PduCount}, - services, utils, Error, Result, Ruma, + services, utils, Error, PduEvent, Result, Ruma, }; /// # `PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}` @@ -156,16 +158,11 @@ pub async fn get_message_events_route( .rooms .timeline .pdus_after(sender_user, &body.room_id, from)? - .take(limit) .filter_map(Result::ok) // Filter out buggy events - .filter(|(_, pdu)| { - services() - .rooms - .state_accessor - .user_can_see_event(sender_user, &body.room_id, &pdu.event_id) - .unwrap_or(false) - }) + .filter(|(_, pdu)| contains_url_filter(pdu, &body.filter)) + .filter(|(_, pdu)| visibility_filter(pdu, sender_user, &body.room_id)) .take_while(|&(k, _)| Some(k) != to) // Stop at `to` + .take(limit) .collect(); for (_, event) in &events_after { @@ -207,16 +204,11 @@ pub async fn get_message_events_route( .rooms .timeline .pdus_until(sender_user, &body.room_id, from)? - .take(limit) .filter_map(Result::ok) // Filter out buggy events - .filter(|(_, pdu)| { - services() - .rooms - .state_accessor - .user_can_see_event(sender_user, &body.room_id, &pdu.event_id) - .unwrap_or(false) - }) + .filter(|(_, pdu)| contains_url_filter(pdu, &body.filter)) + .filter(|(_, pdu)| visibility_filter(pdu, sender_user, &body.room_id)) .take_while(|&(k, _)| Some(k) != to) // Stop at `to` + .take(limit) .collect(); for (_, event) in &events_before { @@ -274,3 +266,24 @@ pub async fn get_message_events_route( Ok(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) +} + +fn contains_url_filter(pdu: &PduEvent, filter: &RoomEventFilter) -> bool { + if filter.url_filter.is_none() { + return true; + } + + let content: Value = from_str(pdu.content.get()).unwrap(); + match filter.url_filter { + Some(UrlFilter::EventsWithoutUrl) => !content["url"].is_string(), + Some(UrlFilter::EventsWithUrl) => content["url"].is_string(), + None => true, + } +}