Add v1/v2 support to gen_event_id() scheme. (#12)
Add v1/v2 and improve reference and content hashing suite. (#12) Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use ruma::{CanonicalJsonObject, OwnedEventId, RoomVersionId};
|
||||
use ruma::{CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId};
|
||||
use serde_json::value::RawValue as RawJsonValue;
|
||||
|
||||
use crate::{Result, debug_error, err, matrix::room_version};
|
||||
@@ -20,13 +20,36 @@ pub fn gen_event_id_canonical_json(
|
||||
Ok((event_id, value))
|
||||
}
|
||||
|
||||
/// Generates a correct eventId for the incoming pdu.
|
||||
/// Generates a correct eventId for the PDU. For v1/v2 incoming PDU's the
|
||||
/// value's event_id is passed through. For all outgoing PDU's and for v3+
|
||||
/// incoming PDU's it is generated.
|
||||
pub fn gen_event_id(
|
||||
value: &CanonicalJsonObject,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result<OwnedEventId> {
|
||||
let room_version_rules = room_version::rules(room_version_id)?;
|
||||
let require_event_id = room_version_rules.event_format.require_event_id;
|
||||
|
||||
// We don't actually generate any event_id for incoming events in v1/v2 rooms,
|
||||
// just pass them through.
|
||||
if let Some(event_id) = require_event_id
|
||||
.then(|| value.get("event_id"))
|
||||
.flatten()
|
||||
.and_then(CanonicalJsonValue::as_str)
|
||||
.map(OwnedEventId::try_from)
|
||||
.transpose()?
|
||||
{
|
||||
return Ok(event_id);
|
||||
}
|
||||
|
||||
// For outgoing v1/v2 add the server part. This has to be our origin but we
|
||||
// can't assert that here.
|
||||
let server_name = require_event_id
|
||||
.then(|| value.get("origin"))
|
||||
.flatten()
|
||||
.and_then(CanonicalJsonValue::as_str);
|
||||
|
||||
let reference_hash = ruma::signatures::reference_hash(value, &room_version_rules)?;
|
||||
|
||||
OwnedEventId::from_parts('$', &reference_hash, None).map_err(Into::into)
|
||||
OwnedEventId::from_parts('$', &reference_hash, server_name).map_err(Into::into)
|
||||
}
|
||||
|
||||
@@ -1,28 +1,71 @@
|
||||
use ruma::{CanonicalJsonObject, RoomVersionId};
|
||||
use tuwunel_core::{Result, err, implement};
|
||||
use ruma::{CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId};
|
||||
use tuwunel_core::{
|
||||
Result, implement,
|
||||
matrix::{event::gen_event_id, room_version},
|
||||
};
|
||||
|
||||
#[implement(super::Service)]
|
||||
pub fn sign_json(&self, object: &mut CanonicalJsonObject) -> Result {
|
||||
use ruma::signatures::sign_json;
|
||||
pub fn gen_id_hash_and_sign_event(
|
||||
&self,
|
||||
object: &mut CanonicalJsonObject,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result<OwnedEventId> {
|
||||
object.remove("event_id");
|
||||
|
||||
let server_name = self.services.globals.server_name().as_str();
|
||||
sign_json(server_name, self.keypair(), object).map_err(Into::into)
|
||||
if room_version::rules(room_version_id)?
|
||||
.event_format
|
||||
.require_event_id
|
||||
{
|
||||
self.gen_id_hash_and_sign_event_v1(object, room_version_id)
|
||||
} else {
|
||||
self.gen_id_hash_and_sign_event_v3(object, room_version_id)
|
||||
}
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
fn gen_id_hash_and_sign_event_v1(
|
||||
&self,
|
||||
object: &mut CanonicalJsonObject,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result<OwnedEventId> {
|
||||
let event_id = gen_event_id(object, room_version_id)?;
|
||||
|
||||
object.insert("event_id".into(), CanonicalJsonValue::String(event_id.clone().into()));
|
||||
|
||||
self.services
|
||||
.server_keys
|
||||
.hash_and_sign_event(object, room_version_id)?;
|
||||
|
||||
Ok(event_id)
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
fn gen_id_hash_and_sign_event_v3(
|
||||
&self,
|
||||
object: &mut CanonicalJsonObject,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result<OwnedEventId> {
|
||||
self.services
|
||||
.server_keys
|
||||
.hash_and_sign_event(object, room_version_id)?;
|
||||
|
||||
let event_id = gen_event_id(object, room_version_id)?;
|
||||
|
||||
object.insert("event_id".into(), CanonicalJsonValue::String(event_id.clone().into()));
|
||||
|
||||
Ok(event_id)
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
pub fn hash_and_sign_event(
|
||||
&self,
|
||||
object: &mut CanonicalJsonObject,
|
||||
room_version: &RoomVersionId,
|
||||
room_version_id: &RoomVersionId,
|
||||
) -> Result {
|
||||
use ruma::signatures::hash_and_sign_event;
|
||||
|
||||
let server_name = &self.services.server.name;
|
||||
let room_version_rules = room_version.rules().ok_or_else(|| {
|
||||
err!(Request(UnsupportedRoomVersion(
|
||||
"Cannot hash and sign event for unknown room version {room_version:?}."
|
||||
)))
|
||||
})?;
|
||||
let room_version_rules = room_version::rules(room_version_id)?;
|
||||
|
||||
hash_and_sign_event(
|
||||
server_name.as_str(),
|
||||
@@ -32,3 +75,12 @@ pub fn hash_and_sign_event(
|
||||
)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[implement(super::Service)]
|
||||
pub fn sign_json(&self, object: &mut CanonicalJsonObject) -> Result {
|
||||
use ruma::signatures::sign_json;
|
||||
|
||||
let server_name = self.services.globals.server_name().as_str();
|
||||
|
||||
sign_json(server_name, self.keypair(), object).map_err(Into::into)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user