Non-reserializing redaction
This commit is contained in:
@@ -4,7 +4,6 @@ pub mod format;
|
|||||||
mod hashes;
|
mod hashes;
|
||||||
mod id;
|
mod id;
|
||||||
mod raw_id;
|
mod raw_id;
|
||||||
mod redact;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
mod unsigned;
|
mod unsigned;
|
||||||
|
|||||||
@@ -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(())
|
|
||||||
}
|
|
||||||
@@ -218,32 +218,23 @@ async fn append_pdu_effects(
|
|||||||
.get_room_version(pdu.room_id())
|
.get_room_version(pdu.room_id())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
match room_version_id {
|
let content: RoomRedactionEventContent;
|
||||||
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => {
|
let event_id = match room_version_id {
|
||||||
if let Some(redact_id) = pdu.redacts()
|
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => 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 = pdu.get_content()?;
|
content = pdu.get_content()?;
|
||||||
if let Some(redact_id) = &content.redacts
|
content.redacts.as_deref()
|
||||||
&& self
|
|
||||||
.services
|
|
||||||
.state_accessor
|
|
||||||
.user_can_redact(redact_id, pdu.sender(), pdu.room_id(), false)
|
|
||||||
.await?
|
|
||||||
{
|
|
||||||
self.redact_pdu(redact_id, pdu, shortroomid)
|
|
||||||
.await?;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
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 =>
|
| TimelineEventType::SpaceChild =>
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
use ruma::EventId;
|
use ruma::{
|
||||||
use tuwunel_core::{
|
EventId, RoomId,
|
||||||
Result, err, implement,
|
canonical_json::{RedactedBecause, redact_in_place},
|
||||||
matrix::event::Event,
|
|
||||||
utils::{self},
|
|
||||||
};
|
};
|
||||||
|
use tuwunel_core::{Result, err, implement, matrix::event::Event};
|
||||||
|
|
||||||
use super::ExtractBody;
|
|
||||||
use crate::rooms::short::ShortRoomId;
|
use crate::rooms::short::ShortRoomId;
|
||||||
|
|
||||||
/// Replace a PDU with the redacted form.
|
/// Replace a PDU with the redacted form.
|
||||||
@@ -17,39 +15,51 @@ pub async fn redact_pdu<Pdu: Event + Send + Sync>(
|
|||||||
reason: &Pdu,
|
reason: &Pdu,
|
||||||
shortroomid: ShortRoomId,
|
shortroomid: ShortRoomId,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
// TODO: Don't reserialize, keep original json
|
|
||||||
let Ok(pdu_id) = self.get_pdu_id(event_id).await else {
|
let Ok(pdu_id) = self.get_pdu_id(event_id).await else {
|
||||||
// If event does not exist, just noop
|
// If event does not exist, just noop
|
||||||
|
// TODO this is actually wrong!
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pdu = self
|
let mut pdu = self
|
||||||
.get_pdu_from_id(&pdu_id)
|
.get_pdu_json_from_id(&pdu_id)
|
||||||
.await
|
.await
|
||||||
.map(Event::into_pdu)
|
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
err!(Database(error!(?pdu_id, ?event_id, ?e, "PDU ID points to invalid PDU.")))
|
err!(Database(error!(?pdu_id, ?event_id, ?e, "PDU ID points to invalid PDU.")))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if let Ok(content) = pdu.get_content::<ExtractBody>()
|
let body = pdu["content"]
|
||||||
&& let Some(body) = content.body
|
.as_object()
|
||||||
{
|
.unwrap()
|
||||||
|
.get("body")
|
||||||
|
.and_then(|body| body.as_str());
|
||||||
|
|
||||||
|
if let Some(body) = body {
|
||||||
self.services
|
self.services
|
||||||
.search
|
.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
|
let room_version_id = self
|
||||||
.services
|
.services
|
||||||
.state
|
.state
|
||||||
.get_room_version(pdu.room_id())
|
.get_room_version(room_id)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
pdu.redact(&room_version_id, reason.to_value())?;
|
let room_version_rules = room_version_id.rules().ok_or_else(|| {
|
||||||
|
err!(Request(UnsupportedRoomVersion(
|
||||||
let obj = utils::to_canonical_object(&pdu).map_err(|e| {
|
"Cannot redact event for unknown room version {room_version_id:?}."
|
||||||
err!(Database(error!(?event_id, ?e, "Failed to convert PDU to canonical JSON")))
|
)))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user