mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-07-27 10:18:30 +00:00
feat(policy-server): Don't fail-closed & refactor references
This commit is contained in:
parent
9465c5df1f
commit
dfda27fadc
3 changed files with 49 additions and 46 deletions
|
@ -1,5 +1,4 @@
|
||||||
mod acl_check;
|
mod acl_check;
|
||||||
mod call_policyserv;
|
|
||||||
mod fetch_and_handle_outliers;
|
mod fetch_and_handle_outliers;
|
||||||
mod fetch_prev;
|
mod fetch_prev;
|
||||||
mod fetch_state;
|
mod fetch_state;
|
||||||
|
@ -7,6 +6,7 @@ mod handle_incoming_pdu;
|
||||||
mod handle_outlier_pdu;
|
mod handle_outlier_pdu;
|
||||||
mod handle_prev_pdu;
|
mod handle_prev_pdu;
|
||||||
mod parse_incoming_pdu;
|
mod parse_incoming_pdu;
|
||||||
|
mod policy_server;
|
||||||
mod resolve_state;
|
mod resolve_state;
|
||||||
mod state_at_incoming;
|
mod state_at_incoming;
|
||||||
mod upgrade_outlier_pdu;
|
mod upgrade_outlier_pdu;
|
||||||
|
|
|
@ -15,14 +15,14 @@ use ruma::{
|
||||||
/// Returns Ok if the policy server allows the event
|
/// Returns Ok if the policy server allows the event
|
||||||
#[implement(super::Service)]
|
#[implement(super::Service)]
|
||||||
#[tracing::instrument(skip_all, level = "debug")]
|
#[tracing::instrument(skip_all, level = "debug")]
|
||||||
pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result {
|
pub async fn ask_policy_server(&self, pdu: &PduEvent, room_id: &RoomId) -> Result<bool> {
|
||||||
if *pdu.event_type() == StateEventType::RoomPolicy.into() {
|
if *pdu.event_type() == StateEventType::RoomPolicy.into() {
|
||||||
debug!(
|
debug!(
|
||||||
room_id = %room_id,
|
room_id = %room_id,
|
||||||
event_type = ?pdu.event_type(),
|
event_type = ?pdu.event_type(),
|
||||||
"Skipping spam check for policy server meta-event"
|
"Skipping spam check for policy server meta-event"
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let Ok(policyserver) = self
|
let Ok(policyserver) = self
|
||||||
.services
|
.services
|
||||||
|
@ -31,19 +31,19 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
|
||||||
.await
|
.await
|
||||||
.map(|c: RoomPolicyEventContent| c)
|
.map(|c: RoomPolicyEventContent| c)
|
||||||
else {
|
else {
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
let via = match policyserver.via {
|
let via = match policyserver.via {
|
||||||
| Some(ref via) => ServerName::parse(via)?,
|
| Some(ref via) => ServerName::parse(via)?,
|
||||||
| None => {
|
| None => {
|
||||||
debug!("No policy server configured for room {room_id}");
|
debug!("No policy server configured for room {room_id}");
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if via.is_empty() {
|
if via.is_empty() {
|
||||||
debug!("Policy server is empty for room {room_id}, skipping spam check");
|
debug!("Policy server is empty for room {room_id}, skipping spam check");
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
}
|
}
|
||||||
if !self.services.state_cache.server_in_room(via, room_id).await {
|
if !self.services.state_cache.server_in_room(via, room_id).await {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -51,7 +51,7 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
|
||||||
via = %via,
|
via = %via,
|
||||||
"Policy server is not in the room, skipping spam check"
|
"Policy server is not in the room, skipping spam check"
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(true);
|
||||||
}
|
}
|
||||||
let outgoing = self
|
let outgoing = self
|
||||||
.services
|
.services
|
||||||
|
@ -85,7 +85,7 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
|
||||||
);
|
);
|
||||||
// Network or policy server errors are treated as non-fatal: event is allowed by
|
// Network or policy server errors are treated as non-fatal: event is allowed by
|
||||||
// default.
|
// default.
|
||||||
return Ok(());
|
return Err(e);
|
||||||
},
|
},
|
||||||
| Err(_) => {
|
| Err(_) => {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -94,7 +94,7 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
|
||||||
room_id = %room_id,
|
room_id = %room_id,
|
||||||
"Policy server request timed out after 10 seconds"
|
"Policy server request timed out after 10 seconds"
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Err!("Request to policy server timed out");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if response.recommendation == "spam" {
|
if response.recommendation == "spam" {
|
||||||
|
@ -107,5 +107,5 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result
|
||||||
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
|
return Err!(Request(Forbidden("Event was marked as spam by policy server")));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(true)
|
||||||
}
|
}
|
|
@ -245,46 +245,49 @@ where
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14-pre. If the event is not a state event, ask the policy server about it
|
if !soft_fail {
|
||||||
if incoming_pdu.state_key.is_none() {
|
// Don't call the below checks on events that have already soft-failed, there's
|
||||||
debug!(
|
// no reason to re-calculate that.
|
||||||
event_id = %incoming_pdu.event_id,"Checking policy server for event");
|
// 14-pre. If the event is not a state event, ask the policy server about it
|
||||||
let policy = self.policyserv_check(&incoming_pdu, room_id);
|
if incoming_pdu.state_key.is_none() {
|
||||||
if let Err(e) = policy.await {
|
debug!(event_id = %incoming_pdu.event_id, "Checking policy server for event");
|
||||||
warn!(
|
match self.ask_policy_server(&incoming_pdu, room_id).await {
|
||||||
event_id = %incoming_pdu.event_id,
|
| Ok(false) => {
|
||||||
error = ?e,
|
warn!(
|
||||||
"Policy server check failed for event"
|
event_id = %incoming_pdu.event_id,
|
||||||
|
"Event has been marked as spam by policy server"
|
||||||
|
);
|
||||||
|
soft_fail = true;
|
||||||
|
},
|
||||||
|
| _ => {
|
||||||
|
debug!(
|
||||||
|
event_id = %incoming_pdu.event_id,
|
||||||
|
"Event has passed policy server check or the policy server was unavailable."
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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!(
|
||||||
|
redact_id = %redact_id,
|
||||||
|
"Checking if redaction is for a soft-failed event"
|
||||||
);
|
);
|
||||||
if !soft_fail {
|
if self
|
||||||
|
.services
|
||||||
|
.pdu_metadata
|
||||||
|
.is_event_soft_failed(&redact_id)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
warn!(
|
||||||
|
redact_id = %redact_id,
|
||||||
|
"Redaction is for a soft-failed event, soft failing the redaction"
|
||||||
|
);
|
||||||
soft_fail = true;
|
soft_fail = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!(
|
|
||||||
event_id = %incoming_pdu.event_id,
|
|
||||||
"Policy server check passed for event"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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!(
|
|
||||||
redact_id = %redact_id,
|
|
||||||
"Checking if redaction is for a soft-failed event"
|
|
||||||
);
|
|
||||||
if self
|
|
||||||
.services
|
|
||||||
.pdu_metadata
|
|
||||||
.is_event_soft_failed(&redact_id)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
warn!(
|
|
||||||
redact_id = %redact_id,
|
|
||||||
"Redaction is for a soft-failed event, soft failing the redaction"
|
|
||||||
);
|
|
||||||
soft_fail = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14. Check if the event passes auth based on the "current state" of the room,
|
// 14. Check if the event passes auth based on the "current state" of the room,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue