mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-11 22:33:01 +02:00
Compare commits
7 commits
5ec8e378c2
...
67cfd5fd99
Author | SHA1 | Date | |
---|---|---|---|
|
67cfd5fd99 |
||
|
124de732e4 |
||
|
333ad204ea |
||
|
33fbc43f76 |
||
|
ea2d508e47 |
||
|
cd479604fe |
||
|
4c30eec355 |
7 changed files with 134 additions and 24 deletions
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -3695,7 +3695,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma"
|
||||
version = "0.10.1"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"js_int",
|
||||
|
@ -3715,7 +3715,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-appservice-api"
|
||||
version = "0.10.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
|
@ -3727,7 +3727,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-client-api"
|
||||
version = "0.18.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"assign",
|
||||
|
@ -3750,7 +3750,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-common"
|
||||
version = "0.13.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"base64 0.22.1",
|
||||
|
@ -3782,7 +3782,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-events"
|
||||
version = "0.28.1"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"indexmap 2.9.0",
|
||||
|
@ -3807,7 +3807,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-federation-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"headers",
|
||||
|
@ -3829,7 +3829,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-identifiers-validation"
|
||||
version = "0.9.5"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"thiserror 2.0.12",
|
||||
|
@ -3838,7 +3838,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-identity-service-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
|
@ -3848,7 +3848,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-macros"
|
||||
version = "0.13.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"proc-macro-crate",
|
||||
|
@ -3863,7 +3863,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-push-gateway-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
|
@ -3875,7 +3875,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruma-signatures"
|
||||
version = "0.15.0"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"ed25519-dalek",
|
||||
|
|
|
@ -350,7 +350,7 @@ version = "0.1.2"
|
|||
[workspace.dependencies.ruma]
|
||||
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
||||
#branch = "conduwuit-changes"
|
||||
rev = "d6870a7fb7f6cccff63f7fd0ff6c581bad80e983"
|
||||
rev = "8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6"
|
||||
features = [
|
||||
"compat",
|
||||
"rand",
|
||||
|
|
|
@ -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
|
||||
|
|
71
src/service/rooms/event_handler/call_policyserv.rs
Normal file
71
src/service/rooms/event_handler/call_policyserv.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use conduwuit::{
|
||||
Err, Event, PduEvent, Result, debug, implement, utils::to_canonical_object, warn,
|
||||
};
|
||||
use ruma::{
|
||||
RoomId, ServerName,
|
||||
api::federation::room::policy::v1::Request as PolicyRequest,
|
||||
canonical_json::to_canonical_value,
|
||||
events::{StateEventType, room::policy::RoomPolicyEventContent},
|
||||
};
|
||||
|
||||
/// Returns Ok if the policy server allows the event
|
||||
#[implement(super::Service)]
|
||||
#[tracing::instrument(skip_all, level = "debug")]
|
||||
pub async fn policyserv_check(&self, pdu: &PduEvent, 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(());
|
||||
},
|
||||
};
|
||||
// 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)
|
||||
.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
|
||||
.sending
|
||||
.send_federation_request(via, PolicyRequest {
|
||||
event_id: pdu.event_id().to_owned(),
|
||||
pdu: Some(outgoing),
|
||||
})
|
||||
.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 {} in room {room_id} was marked as spam by policy server {via}",
|
||||
pdu.event_id().to_owned()
|
||||
);
|
||||
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
mod acl_check;
|
||||
mod call_policyserv;
|
||||
mod fetch_and_handle_outliers;
|
||||
mod fetch_prev;
|
||||
mod fetch_state;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant};
|
||||
|
||||
use conduwuit::{
|
||||
Err, Result, debug, debug_info, err, implement,
|
||||
Err, Event, Result, debug, debug_info, err, implement, info,
|
||||
matrix::{EventTypeExt, PduEvent, StateKey, state_res},
|
||||
trace,
|
||||
utils::stream::{BroadbandExt, ReadyExt},
|
||||
|
@ -44,7 +44,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
return Err!(Request(InvalidParam("Event has been soft failed")));
|
||||
}
|
||||
|
||||
debug!("Upgrading to timeline pdu");
|
||||
debug!("Upgrading pdu {} from outlier to timeline pdu", incoming_pdu.event_id);
|
||||
let timer = Instant::now();
|
||||
let room_version_id = get_room_version_id(create_event)?;
|
||||
|
||||
|
@ -52,7 +52,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
// backwards extremities doing all the checks in this list starting at 1.
|
||||
// These are not timeline events.
|
||||
|
||||
debug!("Resolving state at event");
|
||||
debug!("Resolving state at event {}", incoming_pdu.event_id);
|
||||
let mut state_at_incoming_event = if incoming_pdu.prev_events.len() == 1 {
|
||||
self.state_at_incoming_degree_one(&incoming_pdu).await?
|
||||
} else {
|
||||
|
@ -70,7 +70,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
state_at_incoming_event.expect("we always set this to some above");
|
||||
let room_version = to_room_version(&room_version_id);
|
||||
|
||||
debug!("Performing auth check");
|
||||
debug!("Performing auth check to upgrade {}", incoming_pdu.event_id);
|
||||
// 11. Check the auth of the event passes based on the state of the event
|
||||
let state_fetch_state = &state_at_incoming_event;
|
||||
let state_fetch = |k: StateEventType, s: StateKey| async move {
|
||||
|
@ -80,6 +80,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
self.services.timeline.get_pdu(event_id).await.ok()
|
||||
};
|
||||
|
||||
debug!("running auth check on {}", incoming_pdu.event_id);
|
||||
let auth_check = state_res::event_auth::auth_check(
|
||||
&room_version,
|
||||
&incoming_pdu,
|
||||
|
@ -93,7 +94,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
return Err!(Request(Forbidden("Event has failed auth check with state at the event.")));
|
||||
}
|
||||
|
||||
debug!("Gathering auth events");
|
||||
debug!("Gathering auth events for {}", incoming_pdu.event_id);
|
||||
let auth_events = self
|
||||
.services
|
||||
.state
|
||||
|
@ -111,6 +112,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
ready(auth_events.get(&key).cloned())
|
||||
};
|
||||
|
||||
debug!("running auth check on {} with claimed state auth", incoming_pdu.event_id);
|
||||
let auth_check = state_res::event_auth::auth_check(
|
||||
&room_version,
|
||||
&incoming_pdu,
|
||||
|
@ -121,8 +123,8 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
.map_err(|e| err!(Request(Forbidden("Auth check failed: {e:?}"))))?;
|
||||
|
||||
// Soft fail check before doing state res
|
||||
debug!("Performing soft-fail check");
|
||||
let soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_id)) {
|
||||
debug!("Performing soft-fail check on {}", incoming_pdu.event_id);
|
||||
let mut soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_id)) {
|
||||
| (false, _) => true,
|
||||
| (true, None) => false,
|
||||
| (true, Some(redact_id)) =>
|
||||
|
@ -215,10 +217,26 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu(
|
|||
.await?;
|
||||
}
|
||||
|
||||
// 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()
|
||||
{
|
||||
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 {
|
||||
warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id);
|
||||
if !soft_fail {
|
||||
soft_fail = true;
|
||||
}
|
||||
}
|
||||
debug!("Policy server check passed for event {}", incoming_pdu.event_id);
|
||||
}
|
||||
|
||||
// 14. Check if the event passes auth based on the "current state" of the room,
|
||||
// if not soft fail it
|
||||
if soft_fail {
|
||||
debug!("Soft failing event");
|
||||
info!("Soft failing event {}", incoming_pdu.event_id);
|
||||
// assert!(extremities.is_empty(), "soft_fail extremities empty");
|
||||
let extremities = extremities.iter().map(Borrow::borrow);
|
||||
|
||||
self.services
|
||||
|
|
|
@ -698,6 +698,20 @@ impl Service {
|
|||
.await
|
||||
.saturating_add(uint!(1));
|
||||
|
||||
if state_key.is_none() {
|
||||
if prev_events.is_empty() {
|
||||
warn!("Timeline event had zero prev_events, something broke.");
|
||||
return Err!(Request(Unknown("Timeline event had zero prev_events.")));
|
||||
}
|
||||
if depth.le(&uint!(2)) {
|
||||
warn!(
|
||||
"Had unsafe depth of {depth} in {room_id} when creating non-state event. \
|
||||
Bad!"
|
||||
);
|
||||
return Err!(Request(Unknown("Unsafe depth for non-state event.")));
|
||||
}
|
||||
};
|
||||
|
||||
let mut unsigned = unsigned.unwrap_or_default();
|
||||
|
||||
if let Some(state_key) = &state_key {
|
||||
|
@ -757,6 +771,10 @@ impl Service {
|
|||
ready(auth_events.get(&key))
|
||||
};
|
||||
|
||||
debug!(
|
||||
"running auth check on new {} event by {} in {}",
|
||||
pdu.kind, pdu.sender, pdu.room_id
|
||||
);
|
||||
let auth_check = state_res::auth_check(
|
||||
&room_version,
|
||||
&pdu,
|
||||
|
@ -961,8 +979,9 @@ impl Service {
|
|||
state_lock: &'a RoomMutexGuard,
|
||||
) -> Result<Option<RawPduId>>
|
||||
where
|
||||
Leaves: Iterator<Item = &'a EventId> + Send + 'a,
|
||||
Leaves: Iterator<Item = &'a EventId> + Send + Clone + 'a,
|
||||
{
|
||||
// assert!(new_room_leaves.clone().count() > 0, "extremities are empty");
|
||||
// We append to state before appending the pdu, so we don't have a moment in
|
||||
// time with the pdu without it's state. This is okay because append_pdu can't
|
||||
// fail.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue