From f323faaf92bd24576c0f0521c64149842d79a9e8 Mon Sep 17 00:00:00 2001 From: avdb13 Date: Tue, 28 Jan 2025 23:00:08 +0000 Subject: [PATCH] fix: prevent stripping the room's invite state --- book/changelog.md | 2 ++ src/database/key_value/rooms/state_cache.rs | 37 +++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/book/changelog.md b/book/changelog.md index 7ed662b9..c1342a6b 100644 --- a/book/changelog.md +++ b/book/changelog.md @@ -239,6 +239,8 @@ This will be the first release of Grapevine since it was forked from Conduit ([!158](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/158)) 28. Fix read receipts not being sent over federation (or only arbitrarily late) ([!162](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/162)) +29. Prevent stripping the room's invite state. + ([!159](https://gitlab.computer.surgery/matrix/grapevine/-/merge_requests/159)) ### Added diff --git a/src/database/key_value/rooms/state_cache.rs b/src/database/key_value/rooms/state_cache.rs index c90a18b1..74f2530a 100644 --- a/src/database/key_value/rooms/state_cache.rs +++ b/src/database/key_value/rooms/state_cache.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use ruma::{ - events::{AnyStrippedStateEvent, AnySyncStateEvent}, + events::{AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent}, serde::Raw, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, }; @@ -466,11 +466,36 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { ) })?; - let state = serde_json::from_slice(&state).map_err(|_| { - Error::bad_database( - "Invalid state in userroomid_invitestate.", - ) - })?; + let state: Vec> = + serde_json::from_slice(&state).map_err(|_| { + Error::bad_database( + "Invalid state in userroomid_invitestate.", + ) + })?; + + // The semantics here are omitted by the spec, as the example + // does not strip the membership event: we cast the + // "m.room.member" event to avoid stripping it. + // See: https://spec.matrix.org/latest/server-server-api/#put_matrixfederationv2inviteroomideventid + let state: Vec<_> = state + .into_iter() + .map(|raw| { + match raw.deserialize().map_err(|_| { + Error::bad_database( + "Invalid state in userroomid_invitestate.", + ) + })? { + AnyStateEvent::RoomMember(_) => Ok(raw.cast()), + _ => serde_json::from_str(raw.json().get()) + .map_err(|_| { + Error::bad_database( + "Invalid state in \ + userroomid_invitestate.", + ) + }), + } + }) + .collect::>()?; Ok((room_id, state)) },