diff --git a/src/core/matrix/pdu.rs b/src/core/matrix/pdu.rs index 47f59d22..5dd405eb 100644 --- a/src/core/matrix/pdu.rs +++ b/src/core/matrix/pdu.rs @@ -4,7 +4,6 @@ pub mod format; mod hashes; mod id; mod raw_id; -mod redact; #[cfg(test)] mod tests; mod unsigned; diff --git a/src/core/matrix/pdu/redact.rs b/src/core/matrix/pdu/redact.rs deleted file mode 100644 index a025db2c..00000000 --- a/src/core/matrix/pdu/redact.rs +++ /dev/null @@ -1,35 +0,0 @@ -use ruma::{RoomVersionId, canonical_json::redact_content_in_place}; -use serde_json::{Value as JsonValue, json, value::to_raw_value}; - -use crate::{Error, Result, err, implement}; - -#[implement(super::Pdu)] -pub fn redact(&mut self, room_version_id: &RoomVersionId, reason: JsonValue) -> Result { - self.unsigned = None; - - let mut content = serde_json::from_str(self.content.get()) - .map_err(|e| err!(Request(BadJson("Failed to deserialize content into type: {e}"))))?; - - let room_version_rules = room_version_id.rules().ok_or_else(|| { - err!(Request(UnsupportedRoomVersion( - "Cannot redact event for unknown room version {room_version_id:?}." - ))) - })?; - - redact_content_in_place(&mut content, &room_version_rules.redaction, self.kind.to_string()) - .map_err(|e| Error::Redaction(self.sender.server_name().to_owned(), e))?; - - let reason = serde_json::to_value(reason).expect("Failed to preserialize reason"); - - let redacted_because = json!({ - "redacted_because": reason, - }); - - self.unsigned = to_raw_value(&redacted_because) - .expect("Failed to serialize unsigned") - .into(); - - self.content = to_raw_value(&content).expect("Failed to serialize content"); - - Ok(()) -} diff --git a/src/service/rooms/timeline/append.rs b/src/service/rooms/timeline/append.rs index 902ebc74..c81c321d 100644 --- a/src/service/rooms/timeline/append.rs +++ b/src/service/rooms/timeline/append.rs @@ -218,32 +218,23 @@ async fn append_pdu_effects( .get_room_version(pdu.room_id()) .await?; - match room_version_id { - | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { - if let Some(redact_id) = pdu.redacts() - && self - .services - .state_accessor - .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) - .await? - { - self.redact_pdu(redact_id, pdu, shortroomid) - .await?; - } - }, + let content: RoomRedactionEventContent; + let event_id = match room_version_id { + | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => pdu.redacts(), | _ => { - let content: RoomRedactionEventContent = pdu.get_content()?; - if let Some(redact_id) = &content.redacts - && self - .services - .state_accessor - .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) - .await? - { - self.redact_pdu(redact_id, pdu, shortroomid) - .await?; - } + content = pdu.get_content()?; + content.redacts.as_deref() }, + }; + if let Some(redact_id) = event_id + && self + .services + .state_accessor + .user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false) + .await? + { + self.redact_pdu(redact_id, pdu, shortroomid) + .await?; } }, | TimelineEventType::SpaceChild => diff --git a/src/service/rooms/timeline/redact.rs b/src/service/rooms/timeline/redact.rs index e63666b3..6dd22831 100644 --- a/src/service/rooms/timeline/redact.rs +++ b/src/service/rooms/timeline/redact.rs @@ -1,11 +1,9 @@ -use ruma::EventId; -use tuwunel_core::{ - Result, err, implement, - matrix::event::Event, - utils::{self}, +use ruma::{ + EventId, RoomId, + canonical_json::{RedactedBecause, redact_in_place}, }; +use tuwunel_core::{Result, err, implement, matrix::event::Event}; -use super::ExtractBody; use crate::rooms::short::ShortRoomId; /// Replace a PDU with the redacted form. @@ -17,39 +15,51 @@ pub async fn redact_pdu( reason: &Pdu, shortroomid: ShortRoomId, ) -> Result { - // TODO: Don't reserialize, keep original json let Ok(pdu_id) = self.get_pdu_id(event_id).await else { // If event does not exist, just noop + // TODO this is actually wrong! return Ok(()); }; let mut pdu = self - .get_pdu_from_id(&pdu_id) + .get_pdu_json_from_id(&pdu_id) .await - .map(Event::into_pdu) .map_err(|e| { err!(Database(error!(?pdu_id, ?event_id, ?e, "PDU ID points to invalid PDU."))) })?; - if let Ok(content) = pdu.get_content::() - && let Some(body) = content.body - { + let body = pdu["content"] + .as_object() + .unwrap() + .get("body") + .and_then(|body| body.as_str()); + + if let Some(body) = body { self.services .search - .deindex_pdu(shortroomid, &pdu_id, &body); + .deindex_pdu(shortroomid, &pdu_id, body); } + let room_id = RoomId::parse(pdu["room_id"].as_str().unwrap()).unwrap(); + let room_version_id = self .services .state - .get_room_version(pdu.room_id()) + .get_room_version(room_id) .await?; - pdu.redact(&room_version_id, reason.to_value())?; - - let obj = utils::to_canonical_object(&pdu).map_err(|e| { - err!(Database(error!(?event_id, ?e, "Failed to convert PDU to canonical JSON"))) + let room_version_rules = room_version_id.rules().ok_or_else(|| { + err!(Request(UnsupportedRoomVersion( + "Cannot redact event for unknown room version {room_version_id:?}." + ))) })?; - self.replace_pdu(&pdu_id, &obj).await + redact_in_place( + &mut pdu, + &room_version_rules.redaction, + Some(RedactedBecause::from_json(reason.to_canonical_object())), + ) + .map_err(|err| err!("invalid event: {err}"))?; + + self.replace_pdu(&pdu_id, &pdu).await }