From f965bf2b6aea6e06e32a72ec273782004ef4098f Mon Sep 17 00:00:00 2001 From: Lambda Date: Fri, 30 Aug 2024 22:11:29 +0000 Subject: [PATCH 1/2] Implement MSC4185 --- Cargo.toml | 5 +- src/api/client_server.rs | 2 + src/api/client_server/event_visibility.rs | 60 +++++++++++++++++++++++ src/api/client_server/unversioned.rs | 8 +-- src/main.rs | 3 +- 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/api/client_server/event_visibility.rs diff --git a/Cargo.toml b/Cargo.toml index d7682651..b099c632 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -147,7 +147,10 @@ xdg = "2.5.2" nix = { version = "0.29", features = ["resource"] } [features] -default = ["rocksdb", "sqlite", "systemd"] +# needed for ruma Request/Response derives +client = [] +server = [] +default = ["rocksdb", "sqlite", "systemd", "server"] # Keep sorted jemalloc = ["dep:tikv-jemallocator"] diff --git a/src/api/client_server.rs b/src/api/client_server.rs index 65c5985d..1a595289 100644 --- a/src/api/client_server.rs +++ b/src/api/client_server.rs @@ -6,6 +6,7 @@ mod config; mod context; mod device; mod directory; +mod event_visibility; mod filter; mod keys; mod media; @@ -40,6 +41,7 @@ pub(crate) use config::*; pub(crate) use context::*; pub(crate) use device::*; pub(crate) use directory::*; +pub(crate) use event_visibility::*; pub(crate) use filter::*; pub(crate) use keys::*; pub(crate) use media::*; diff --git a/src/api/client_server/event_visibility.rs b/src/api/client_server/event_visibility.rs new file mode 100644 index 00000000..36b1d9b2 --- /dev/null +++ b/src/api/client_server/event_visibility.rs @@ -0,0 +1,60 @@ +//! Implementation of [MSC4185](https://github.com/matrix-org/matrix-spec-proposals/pull/4185) + +use ruma::{ + api::{request, response, Metadata}, + metadata, OwnedEventId, OwnedRoomId, OwnedUserId, +}; + +use crate::{services, Ar, Ra, Result}; + +const METADATA: Metadata = metadata! { + method: GET, + rate_limited: true, + authentication: AccessToken, + + history: { + unstable => "/_matrix/client/unstable/net.tadzik/can_user_see_event/:room_id/:user_id/:event_id", + }, +}; + +#[request] +#[allow(clippy::struct_field_names)] +pub(crate) struct Request { + #[ruma_api(path)] + pub(crate) room_id: OwnedRoomId, + + #[ruma_api(path)] + pub(crate) user_id: OwnedUserId, + + #[ruma_api(path)] + pub(crate) event_id: OwnedEventId, +} + +#[response] +pub(crate) struct Response { + #[ruma_api(body)] + pub(crate) is_visible: bool, +} + +pub(crate) async fn can_user_see_event_route( + body: Ar, +) -> Result> { + let Ok(true) = services().rooms.state_accessor.user_can_see_event( + body.sender_user.as_ref().expect("user is authenticated"), + &body.room_id, + &body.event_id, + ) else { + return Err(crate::Error::BadRequest( + ruma::api::client::error::ErrorKind::Unauthorized, + "event is not visible to requesting user", + )); + }; + + Ok(Ra(Response { + is_visible: services().rooms.state_accessor.user_can_see_event( + &body.user_id, + &body.room_id, + &body.event_id, + )?, + })) +} diff --git a/src/api/client_server/unversioned.rs b/src/api/client_server/unversioned.rs index 8ea8136c..78d30a9d 100644 --- a/src/api/client_server/unversioned.rs +++ b/src/api/client_server/unversioned.rs @@ -29,10 +29,10 @@ pub(crate) async fn get_supported_versions_route( "v1.4".to_owned(), "v1.5".to_owned(), ], - unstable_features: BTreeMap::from_iter([( - "org.matrix.e2e_cross_signing".to_owned(), - true, - )]), + unstable_features: BTreeMap::from_iter([ + ("org.matrix.e2e_cross_signing".to_owned(), true), + ("org.matrix.msc4185".to_owned(), true), + ]), }; Ok(Ra(resp)) diff --git a/src/main.rs b/src/main.rs index 69ba7023..bb78fbd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -414,7 +414,8 @@ fn routes(config: &Config) -> Router { .ruma_route(c2s::get_relating_events_with_rel_type_and_event_type_route) .ruma_route(c2s::get_relating_events_with_rel_type_route) .ruma_route(c2s::get_relating_events_route) - .ruma_route(c2s::get_hierarchy_route); + .ruma_route(c2s::get_hierarchy_route) + .ruma_route(c2s::can_user_see_event_route); // Ruma doesn't have support for multiple paths for a single endpoint yet, // and these routes share one Ruma request / response type pair with From 1ba96b95340559d405155f47cf41c0a8928d0935 Mon Sep 17 00:00:00 2001 From: Lambda Date: Fri, 30 Aug 2024 22:18:50 +0000 Subject: [PATCH 2/2] Mark events as not visible when they're not found or in the wrong room --- src/service/rooms/state_accessor.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/service/rooms/state_accessor.rs b/src/service/rooms/state_accessor.rs index b9e9f702..5a15718e 100644 --- a/src/service/rooms/state_accessor.rs +++ b/src/service/rooms/state_accessor.rs @@ -215,6 +215,14 @@ impl Service { ) -> Result { let lookup = Lookup::VisibilityForUser; + let Some(pdu) = services().rooms.timeline.get_pdu(event_id)? else { + return Ok(false); + }; + + if pdu.room_id() != room_id { + return Ok(false); + } + let Some(shortstatehash) = self.pdu_shortstatehash(event_id)? else { return Ok(true); };