policy server following maybe???

(cherry picked from commit e1c06e10f6ce27b570682989fed0defda0fe09a1)
This commit is contained in:
nexy7574 2025-06-19 20:26:39 +01:00
parent 17930708d8
commit 57879c1be5
No known key found for this signature in database
GPG key ID: 0FA334385D0B689F
6 changed files with 329 additions and 427 deletions

655
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -350,7 +350,7 @@ version = "0.1.2"
[workspace.dependencies.ruma]
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
#branch = "conduwuit-changes"
rev = "9b65f83981f6f53d185ce77da37aaef9dfd764a9"
rev = "781606d1fafbf2daa220fd354d9ad0479a308cd1"
features = [
"compat",
"rand",
@ -556,11 +556,11 @@ rev = "1e64095a8051a1adf0d1faa307f9f030889ec2aa"
git = "https://forgejo.ellis.link/continuwuation/tracing"
rev = "1e64095a8051a1adf0d1faa307f9f030889ec2aa"
# adds a tab completion callback: https://forgejo.ellis.link/continuwuation/rustyline-async/src/branch/main/.patchy/0002-add-tab-completion-callback.patch
# adds event for CTRL+\: https://forgejo.ellis.link/continuwuation/rustyline-async/src/branch/main/.patchy/0001-add-event-for-ctrl.patch
# adds a tab completion callback: https://forgejo.ellis.link/continuwuation/rustyline-async/commit/de26100b0db03e419a3d8e1dd26895d170d1fe50
# adds event for CTRL+\: https://forgejo.ellis.link/continuwuation/rustyline-async/commit/67d8c49aeac03a5ef4e818f663eaa94dd7bf339b
[patch.crates-io.rustyline-async]
git = "https://forgejo.ellis.link/continuwuation/rustyline-async"
rev = "e9f01cf8c6605483cb80b3b0309b400940493d7f"
rev = "deaeb0694e2083f53d363b648da06e10fc13900c"
# adds LIFO queue scheduling; this should be updated with PR progress.
[patch.crates-io.event-listener]
@ -580,11 +580,12 @@ rev = "9c8e51510c35077df888ee72a36b4b05637147da"
git = "https://forgejo.ellis.link/continuwuation/hyper-util"
rev = "e4ae7628fe4fcdacef9788c4c8415317a4489941"
# Allows no-aaaa option in resolv.conf
# Use 1-indexed line numbers when displaying parse error messages
# allows no-aaaa option in resolv.conf
# bumps rust edition and toolchain to 1.86.0 and 2024
# use sat_add on line number errors
[patch.crates-io.resolv-conf]
git = "https://forgejo.ellis.link/continuwuation/resolv-conf"
rev = "56251316cc4127bcbf36e68ce5e2093f4d33e227"
rev = "200e958941d522a70c5877e3d846f55b5586c68d"
#
# Our crates

View file

@ -5,7 +5,7 @@ use futures::{
future::{OptionFuture, join3},
};
use ruma::{
Int, OwnedUserId, RoomVersionId, UserId,
EventId, Int, OwnedUserId, RoomVersionId, UserId,
events::room::{
create::RoomCreateEventContent,
join_rules::{JoinRule, RoomJoinRulesEventContent},
@ -217,8 +217,9 @@ where
}
/*
// TODO: In the past this code caused problems federating with synapse, maybe this has been
// resolved already. Needs testing.
// TODO: In the past this code was commented as it caused problems with Synapse. This is no
// longer the case. This needs to be implemented.
// See also: https://github.com/ruma/ruma/pull/2064
//
// 2. Reject if auth_events
// a. auth_events cannot have duplicate keys since it's a BTree

View file

@ -0,0 +1,54 @@
use conduwuit::{Err, Result, debug, implement, trace, warn};
use ruma::{
EventId, OwnedEventId, OwnedServerName, RoomId, ServerName,
api::federation::room::policy::v1::{Request as PolicyRequest, Response as PolicyResponse},
events::{
StateEventType,
room::{
policy::{PolicyServerResponseContent, RoomPolicyEventContent},
server_acl::RoomServerAclEventContent,
},
},
};
use serde::{Deserialize, Serialize};
/// Returns Ok if the policy server allows the event
#[implement(super::Service)]
#[tracing::instrument(skip_all, level = "debug")]
pub async fn policyserv_check(&self, event_id: &EventId, room_id: &RoomId) -> Result {
let Ok(policyserver) = self
.services
.state_accessor
.room_state_get_content(room_id, &StateEventType::RoomPolicy, "")
.await
.map(|c: RoomPolicyEventContent| c)
else {
return Ok(());
};
let via = match policyserver.via {
| Some(ref via) => ServerName::parse(via)?,
| None => {
debug!("No policy server configured for room {room_id}");
return Ok(());
},
};
let response = self
.services
.sending
.send_federation_request(via, PolicyRequest { event_id: event_id.to_owned() })
.await;
let response = match response {
| Ok(response) => response,
| Err(e) => {
warn!("Failed to contact policy server {via} for room {room_id}: {e}");
return Ok(());
},
};
if response.recommendation == "spam" {
warn!("Event {event_id} in room {room_id} was marked as spam by policy server {via}");
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
};
Ok(())
}

View file

@ -1,4 +1,5 @@
mod acl_check;
mod call_policyserv;
mod fetch_and_handle_outliers;
mod fetch_prev;
mod fetch_state;

View file

@ -1,12 +1,6 @@
use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant};
use conduwuit::{
Err, Result, debug, debug_info, err, implement,
matrix::{EventTypeExt, PduEvent, StateKey, state_res},
trace,
utils::stream::{BroadbandExt, ReadyExt},
warn,
};
use conduwuit::{Err, Result, debug, debug_info, err, implement, info, matrix::{EventTypeExt, PduEvent, StateKey, state_res}, trace, utils::stream::{BroadbandExt, ReadyExt}, warn, Event};
use futures::{FutureExt, StreamExt, future::ready};
use ruma::{CanonicalJsonValue, RoomId, ServerName, events::StateEventType};
@ -242,6 +236,20 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
return Err!(Request(InvalidParam("Event has been soft failed")));
}
// 15. If the event is not a state event, ask the policy server about it
if incoming_pdu.state_key.is_none() {
debug!("Checking policy server for event {}", incoming_pdu.event_id);
let policy = self.policyserv_check(
&incoming_pdu.event_id,
room_id,
);
if let Err(e) = policy.await {
warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id);
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
}
debug!("Policy server check passed for event {}", incoming_pdu.event_id);
}
// Now that the event has passed all auth it is added into the timeline.
// We use the `state_at_event` instead of `state_after` so we accurately
// represent the state for this event.