prevent retry for missing keys later in join process

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-11-10 08:39:30 +00:00
parent 7e087bb93c
commit f290d1a9c8
3 changed files with 91 additions and 36 deletions

View file

@ -7,13 +7,19 @@ mod verify;
use std::{collections::BTreeMap, sync::Arc, time::Duration};
use conduit::{implement, utils::timepoint_from_now, Result, Server};
use conduit::{
implement,
utils::{timepoint_from_now, IterStream},
Result, Server,
};
use database::{Deserialized, Json, Map};
use futures::StreamExt;
use ruma::{
api::federation::discovery::{ServerSigningKeys, VerifyKey},
serde::Raw,
signatures::{Ed25519KeyPair, PublicKeyMap, PublicKeySet},
MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, ServerName, ServerSigningKeyId,
CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, RoomVersionId, ServerName,
ServerSigningKeyId,
};
use serde_json::value::RawValue as RawJsonValue;
@ -107,7 +113,23 @@ async fn add_signing_keys(&self, new_keys: ServerSigningKeys) {
}
#[implement(Service)]
async fn verify_key_exists(&self, origin: &ServerName, key_id: &ServerSigningKeyId) -> bool {
pub async fn required_keys_exist(&self, object: &CanonicalJsonObject, version: &RoomVersionId) -> bool {
use ruma::signatures::required_keys;
let Ok(required_keys) = required_keys(object, version) else {
return false;
};
required_keys
.iter()
.flat_map(|(server, key_ids)| key_ids.iter().map(move |key_id| (server, key_id)))
.stream()
.all(|(server, key_id)| self.verify_key_exists(server, key_id))
.await
}
#[implement(Service)]
pub async fn verify_key_exists(&self, origin: &ServerName, key_id: &ServerSigningKeyId) -> bool {
type KeysMap<'a> = BTreeMap<&'a ServerSigningKeyId, &'a RawJsonValue>;
let Ok(keys) = self

View file

@ -16,6 +16,26 @@ pub async fn validate_and_add_event_id(
Ok((event_id, value))
}
#[implement(super::Service)]
pub async fn validate_and_add_event_id_no_fetch(
&self, pdu: &RawJsonValue, room_version: &RoomVersionId,
) -> Result<(OwnedEventId, CanonicalJsonObject)> {
let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version)?;
if !self.required_keys_exist(&value, room_version).await {
return Err!(BadServerResponse(debug_warn!(
"Event {event_id} cannot be verified: missing keys."
)));
}
if let Err(e) = self.verify_event(&value, Some(room_version)).await {
return Err!(BadServerResponse(debug_error!("Event {event_id} failed verification: {e:?}")));
}
value.insert("event_id".into(), CanonicalJsonValue::String(event_id.as_str().into()));
Ok((event_id, value))
}
#[implement(super::Service)]
pub async fn verify_event(
&self, event: &CanonicalJsonObject, room_version: Option<&RoomVersionId>,