mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-17 15:51:23 +01:00
generalize get_room_version
There are other fields of `m.room.create` events that are useful to individually extract without caring about the values of other fields.
This commit is contained in:
parent
c9c30fba30
commit
a4e1522875
4 changed files with 69 additions and 24 deletions
|
|
@ -38,6 +38,7 @@ use crate::{
|
||||||
service::{
|
service::{
|
||||||
globals::SigningKeys,
|
globals::SigningKeys,
|
||||||
pdu::{gen_event_id_canonical_json, PduBuilder},
|
pdu::{gen_event_id_canonical_json, PduBuilder},
|
||||||
|
rooms::state::ExtractVersion,
|
||||||
},
|
},
|
||||||
services, utils, Ar, Error, PduEvent, Ra, Result,
|
services, utils, Ar, Error, PduEvent, Ra, Result,
|
||||||
};
|
};
|
||||||
|
|
@ -1324,8 +1325,10 @@ pub(crate) async fn invite_helper(
|
||||||
(pdu, pdu_json, invite_room_state)
|
(pdu, pdu_json, invite_room_state)
|
||||||
};
|
};
|
||||||
|
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(room_id)?;
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(room_id)?;
|
||||||
|
|
||||||
let response = services()
|
let response = services()
|
||||||
.sending
|
.sending
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ use crate::{
|
||||||
service::{
|
service::{
|
||||||
globals::SigningKeys,
|
globals::SigningKeys,
|
||||||
pdu::{gen_event_id_canonical_json, PduBuilder},
|
pdu::{gen_event_id_canonical_json, PduBuilder},
|
||||||
|
rooms::state::ExtractVersion,
|
||||||
},
|
},
|
||||||
services,
|
services,
|
||||||
utils::{self, dbg_truncate_str, MxcData},
|
utils::{self, dbg_truncate_str, MxcData},
|
||||||
|
|
@ -712,7 +713,10 @@ pub(crate) fn parse_incoming_pdu(
|
||||||
"Invalid room id in pdu",
|
"Invalid room id in pdu",
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let room_version_id = services().rooms.state.get_room_version(&room_id)?;
|
let room_version_id = services()
|
||||||
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&room_id)?;
|
||||||
|
|
||||||
let Ok((event_id, value)) =
|
let Ok((event_id, value)) =
|
||||||
gen_event_id_canonical_json(pdu, &room_version_id)
|
gen_event_id_canonical_json(pdu, &room_version_id)
|
||||||
|
|
@ -754,7 +758,12 @@ pub(crate) async fn send_transaction_message_route(
|
||||||
"Invalid room id in pdu",
|
"Invalid room id in pdu",
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
if services().rooms.state.get_room_version(&room_id).is_err() {
|
if services()
|
||||||
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&room_id)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
debug!(%room_id, "This server is not in the room");
|
debug!(%room_id, "This server is not in the room");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1514,8 +1523,10 @@ pub(crate) async fn create_join_event_template_route(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(&body.room_id)?;
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&body.room_id)?;
|
||||||
if !body.ver.contains(&room_version_id) {
|
if !body.ver.contains(&room_version_id) {
|
||||||
return Err(Error::BadRequest(
|
return Err(Error::BadRequest(
|
||||||
ErrorKind::IncompatibleRoomVersion {
|
ErrorKind::IncompatibleRoomVersion {
|
||||||
|
|
@ -1620,7 +1631,8 @@ async fn create_join_event(
|
||||||
|
|
||||||
// We do not add the event_id field to the pdu here because of signature and
|
// We do not add the event_id field to the pdu here because of signature and
|
||||||
// hashes checks
|
// hashes checks
|
||||||
let room_version_id = services().rooms.state.get_room_version(room_id)?;
|
let room_version_id =
|
||||||
|
services().rooms.state.get_create_content::<ExtractVersion>(room_id)?;
|
||||||
let Ok((event_id, value)) =
|
let Ok((event_id, value)) =
|
||||||
gen_event_id_canonical_json(pdu, &room_version_id)
|
gen_event_id_canonical_json(pdu, &room_version_id)
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ use std::{
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::client::error::ErrorKind,
|
api::client::error::ErrorKind,
|
||||||
events::{
|
events::{
|
||||||
room::{create::RoomCreateEventContent, member::MembershipState},
|
room::member::MembershipState, AnyStrippedStateEvent, StateEventType,
|
||||||
AnyStrippedStateEvent, StateEventType, TimelineEventType,
|
TimelineEventType,
|
||||||
},
|
},
|
||||||
serde::Raw,
|
serde::Raw,
|
||||||
state_res::{self, StateMap},
|
state_res::{self, StateMap},
|
||||||
EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId,
|
EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::{de::DeserializeOwned, Deserialize};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
use super::{short::ShortStateHash, state_compressor::CompressedStateEvent};
|
use super::{short::ShortStateHash, state_compressor::CompressedStateEvent};
|
||||||
|
|
@ -31,6 +31,26 @@ mod data;
|
||||||
|
|
||||||
pub(crate) use data::Data;
|
pub(crate) use data::Data;
|
||||||
|
|
||||||
|
pub(crate) trait ExtractCreateContent: DeserializeOwned {
|
||||||
|
type Extract;
|
||||||
|
|
||||||
|
fn extract(self) -> Self::Extract;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract the `room_version` from an `m.room.create` event
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub(crate) struct ExtractVersion {
|
||||||
|
room_version: RoomVersionId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtractCreateContent for ExtractVersion {
|
||||||
|
type Extract = RoomVersionId;
|
||||||
|
|
||||||
|
fn extract(self) -> Self::Extract {
|
||||||
|
self.room_version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct Service {
|
pub(crate) struct Service {
|
||||||
pub(crate) db: &'static dyn Data,
|
pub(crate) db: &'static dyn Data,
|
||||||
}
|
}
|
||||||
|
|
@ -315,22 +335,22 @@ impl Service {
|
||||||
self.db.set_room_state(room_id, shortstatehash)
|
self.db.set_room_state(room_id, shortstatehash)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the room's version.
|
/// Returns the value of a field of an `m.room.create` event's `content`.
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub(crate) fn get_room_version(
|
pub(crate) fn get_create_content<T: ExtractCreateContent>(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
) -> Result<RoomVersionId> {
|
) -> Result<T::Extract> {
|
||||||
let create_event = services().rooms.state_accessor.room_state_get(
|
let create_event = services().rooms.state_accessor.room_state_get(
|
||||||
room_id,
|
room_id,
|
||||||
&StateEventType::RoomCreate,
|
&StateEventType::RoomCreate,
|
||||||
"",
|
"",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let create_event_content: RoomCreateEventContent = create_event
|
let content_field = create_event
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|create_event| {
|
.map(|create_event| {
|
||||||
serde_json::from_str(create_event.content.get()).map_err(
|
serde_json::from_str::<T>(create_event.content.get()).map_err(
|
||||||
|error| {
|
|error| {
|
||||||
warn!(%error, "Invalid create event");
|
warn!(%error, "Invalid create event");
|
||||||
Error::BadDatabase("Invalid create event in db.")
|
Error::BadDatabase("Invalid create event in db.")
|
||||||
|
|
@ -345,7 +365,7 @@ impl Service {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(create_event_content.room_version)
|
Ok(content_field.extract())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ use crate::{
|
||||||
appservice::NamespaceRegex,
|
appservice::NamespaceRegex,
|
||||||
globals::{marker, SigningKeys},
|
globals::{marker, SigningKeys},
|
||||||
pdu::{EventHash, PduBuilder},
|
pdu::{EventHash, PduBuilder},
|
||||||
|
rooms::state::ExtractVersion,
|
||||||
},
|
},
|
||||||
services,
|
services,
|
||||||
utils::{self, on_demand_hashmap::KeyToken, room_version::RoomVersion},
|
utils::{self, on_demand_hashmap::KeyToken, room_version::RoomVersion},
|
||||||
|
|
@ -476,8 +477,10 @@ impl Service {
|
||||||
|
|
||||||
match pdu.kind {
|
match pdu.kind {
|
||||||
TimelineEventType::RoomRedaction => {
|
TimelineEventType::RoomRedaction => {
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||||
let room_version = RoomVersion::try_from(&room_version_id)?;
|
let room_version = RoomVersion::try_from(&room_version_id)?;
|
||||||
if room_version.redaction_event_redacts_in_content {
|
if room_version.redaction_event_redacts_in_content {
|
||||||
let content = serde_json::from_str::<
|
let content = serde_json::from_str::<
|
||||||
|
|
@ -774,8 +777,11 @@ impl Service {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// If there was no create event yet, assume we are creating a room
|
// If there was no create event yet, assume we are creating a room
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(room_id).or_else(|_| {
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(room_id)
|
||||||
|
.or_else(|_| {
|
||||||
if event_type == TimelineEventType::RoomCreate {
|
if event_type == TimelineEventType::RoomCreate {
|
||||||
let content =
|
let content =
|
||||||
serde_json::from_str::<RoomCreateEventContent>(
|
serde_json::from_str::<RoomCreateEventContent>(
|
||||||
|
|
@ -1064,8 +1070,10 @@ impl Service {
|
||||||
// If redaction event is not authorized, do not append it to the
|
// If redaction event is not authorized, do not append it to the
|
||||||
// timeline
|
// timeline
|
||||||
if pdu.kind == TimelineEventType::RoomRedaction {
|
if pdu.kind == TimelineEventType::RoomRedaction {
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||||
let room_version = RoomVersion::try_from(&room_version_id)?;
|
let room_version = RoomVersion::try_from(&room_version_id)?;
|
||||||
if room_version.redaction_event_redacts_in_content {
|
if room_version.redaction_event_redacts_in_content {
|
||||||
let content =
|
let content =
|
||||||
|
|
@ -1257,8 +1265,10 @@ impl Service {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let room_version_id =
|
let room_version_id = services()
|
||||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
.rooms
|
||||||
|
.state
|
||||||
|
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||||
pdu.redact(room_version_id, reason)?;
|
pdu.redact(room_version_id, reason)?;
|
||||||
|
|
||||||
self.replace_pdu(
|
self.replace_pdu(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue