diff --git a/src/service/rooms/event_handler/call_policyserv.rs b/src/service/rooms/event_handler/call_policyserv.rs index 804c77eb..894e28af 100644 --- a/src/service/rooms/event_handler/call_policyserv.rs +++ b/src/service/rooms/event_handler/call_policyserv.rs @@ -26,20 +26,11 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result return Ok(()); }, }; - // TODO: dont do *this* - let pdu_json = self.services.timeline.get_pdu_json(pdu.event_id()).await?; let outgoing = self .services .sending - .convert_to_outgoing_federation_event(pdu_json) + .convert_to_outgoing_federation_event(pdu.to_canonical_object()) .await; - // let s = match serde_json::to_string(outgoing.as_ref()) { - // | Ok(s) => s, - // | Err(e) => { - // warn!("Failed to convert pdu {} to outgoing federation event: {e}", - // pdu.event_id()); return Err!(Request(InvalidParam("Failed to convert PDU - // to outgoing event."))); }, - // }; debug!("Checking pdu {outgoing:?} for spam with policy server {via} for room {room_id}"); let response = self .services @@ -52,14 +43,21 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result let response = match response { | Ok(response) => response, | Err(e) => { - warn!("Failed to contact policy server {via} for room {room_id}: {e}"); + warn!( + via = %via, + event_id = %pdu.event_id(), + room_id = %room_id, + "Failed to contact policy server: {e}" + ); return Ok(()); }, }; if response.recommendation == "spam" { warn!( - "Event {} in room {room_id} was marked as spam by policy server {via}", - pdu.event_id().to_owned() + via = %via, + event_id = %pdu.event_id(), + room_id = %room_id, + "Event was marked as spam by policy server", ); return Err!(Request(Forbidden("Event was marked as spam by policy server"))); } diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 081b3892..39e46630 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -222,9 +222,7 @@ where } // 14-pre. If the event is not a state event, ask the policy server about it - if incoming_pdu.state_key.is_none() - && incoming_pdu.sender().server_name() != self.services.globals.server_name() - { + if incoming_pdu.state_key.is_none() { debug!("Checking policy server for event {}", incoming_pdu.event_id); let policy = self.policyserv_check(&incoming_pdu, room_id); if let Err(e) = policy.await { @@ -236,6 +234,24 @@ where debug!("Policy server check passed for event {}", incoming_pdu.event_id); } + // Additionally, if this is a redaction for a soft-failed event, we soft-fail it + // also + if let Some(redact_id) = incoming_pdu.redacts_id(&room_version_id) { + debug!("Checking if redaction {} is for a soft-failed event", redact_id); + if self + .services + .pdu_metadata + .is_event_soft_failed(&redact_id) + .await + { + warn!( + "Redaction {} is for a soft-failed event, soft failing the redaction", + redact_id + ); + soft_fail = true; + } + } + // 14. Check if the event passes auth based on the "current state" of the room, // if not soft fail it if soft_fail { diff --git a/src/service/rooms/timeline/create.rs b/src/service/rooms/timeline/create.rs index 20ccaf56..6301d785 100644 --- a/src/service/rooms/timeline/create.rs +++ b/src/service/rooms/timeline/create.rs @@ -165,6 +165,17 @@ pub async fn create_hash_and_sign_event( return Err!(Request(Forbidden("Event is not authorized."))); } + // Check with the policy server + if self + .services + .event_handler + .policyserv_check(&pdu, room_id) + .await + .is_err() + { + return Err!(Request(Forbidden(debug_warn!("Policy server marked this event as spam")))); + } + // Hash and sign let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| { err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))