mirror of
https://gitlab.computer.surgery/matrix/grapevine.git
synced 2025-12-16 15:21:24 +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::{
|
||||
globals::SigningKeys,
|
||||
pdu::{gen_event_id_canonical_json, PduBuilder},
|
||||
rooms::state::ExtractVersion,
|
||||
},
|
||||
services, utils, Ar, Error, PduEvent, Ra, Result,
|
||||
};
|
||||
|
|
@ -1324,8 +1325,10 @@ pub(crate) async fn invite_helper(
|
|||
(pdu, pdu_json, invite_room_state)
|
||||
};
|
||||
|
||||
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 response = services()
|
||||
.sending
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ use crate::{
|
|||
service::{
|
||||
globals::SigningKeys,
|
||||
pdu::{gen_event_id_canonical_json, PduBuilder},
|
||||
rooms::state::ExtractVersion,
|
||||
},
|
||||
services,
|
||||
utils::{self, dbg_truncate_str, MxcData},
|
||||
|
|
@ -712,7 +713,10 @@ pub(crate) fn parse_incoming_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)) =
|
||||
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",
|
||||
))?;
|
||||
|
||||
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");
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1514,8 +1523,10 @@ pub(crate) async fn create_join_event_template_route(
|
|||
}
|
||||
}
|
||||
|
||||
let room_version_id =
|
||||
services().rooms.state.get_room_version(&body.room_id)?;
|
||||
let room_version_id = services()
|
||||
.rooms
|
||||
.state
|
||||
.get_create_content::<ExtractVersion>(&body.room_id)?;
|
||||
if !body.ver.contains(&room_version_id) {
|
||||
return Err(Error::BadRequest(
|
||||
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
|
||||
// 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)) =
|
||||
gen_event_id_canonical_json(pdu, &room_version_id)
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ use std::{
|
|||
use ruma::{
|
||||
api::client::error::ErrorKind,
|
||||
events::{
|
||||
room::{create::RoomCreateEventContent, member::MembershipState},
|
||||
AnyStrippedStateEvent, StateEventType, TimelineEventType,
|
||||
room::member::MembershipState, AnyStrippedStateEvent, StateEventType,
|
||||
TimelineEventType,
|
||||
},
|
||||
serde::Raw,
|
||||
state_res::{self, StateMap},
|
||||
EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use tracing::warn;
|
||||
|
||||
use super::{short::ShortStateHash, state_compressor::CompressedStateEvent};
|
||||
|
|
@ -31,6 +31,26 @@ mod 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) db: &'static dyn Data,
|
||||
}
|
||||
|
|
@ -315,22 +335,22 @@ impl Service {
|
|||
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))]
|
||||
pub(crate) fn get_room_version(
|
||||
pub(crate) fn get_create_content<T: ExtractCreateContent>(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> Result<RoomVersionId> {
|
||||
) -> Result<T::Extract> {
|
||||
let create_event = services().rooms.state_accessor.room_state_get(
|
||||
room_id,
|
||||
&StateEventType::RoomCreate,
|
||||
"",
|
||||
)?;
|
||||
|
||||
let create_event_content: RoomCreateEventContent = create_event
|
||||
let content_field = create_event
|
||||
.as_ref()
|
||||
.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| {
|
||||
warn!(%error, "Invalid create event");
|
||||
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))]
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use crate::{
|
|||
appservice::NamespaceRegex,
|
||||
globals::{marker, SigningKeys},
|
||||
pdu::{EventHash, PduBuilder},
|
||||
rooms::state::ExtractVersion,
|
||||
},
|
||||
services,
|
||||
utils::{self, on_demand_hashmap::KeyToken, room_version::RoomVersion},
|
||||
|
|
@ -476,8 +477,10 @@ impl Service {
|
|||
|
||||
match pdu.kind {
|
||||
TimelineEventType::RoomRedaction => {
|
||||
let room_version_id =
|
||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
||||
let room_version_id = services()
|
||||
.rooms
|
||||
.state
|
||||
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||
let room_version = RoomVersion::try_from(&room_version_id)?;
|
||||
if room_version.redaction_event_redacts_in_content {
|
||||
let content = serde_json::from_str::<
|
||||
|
|
@ -774,8 +777,11 @@ impl Service {
|
|||
.collect();
|
||||
|
||||
// If there was no create event yet, assume we are creating a room
|
||||
let room_version_id =
|
||||
services().rooms.state.get_room_version(room_id).or_else(|_| {
|
||||
let room_version_id = services()
|
||||
.rooms
|
||||
.state
|
||||
.get_create_content::<ExtractVersion>(room_id)
|
||||
.or_else(|_| {
|
||||
if event_type == TimelineEventType::RoomCreate {
|
||||
let content =
|
||||
serde_json::from_str::<RoomCreateEventContent>(
|
||||
|
|
@ -1064,8 +1070,10 @@ impl Service {
|
|||
// If redaction event is not authorized, do not append it to the
|
||||
// timeline
|
||||
if pdu.kind == TimelineEventType::RoomRedaction {
|
||||
let room_version_id =
|
||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
||||
let room_version_id = services()
|
||||
.rooms
|
||||
.state
|
||||
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||
let room_version = RoomVersion::try_from(&room_version_id)?;
|
||||
if room_version.redaction_event_redacts_in_content {
|
||||
let content =
|
||||
|
|
@ -1257,8 +1265,10 @@ impl Service {
|
|||
)?;
|
||||
}
|
||||
|
||||
let room_version_id =
|
||||
services().rooms.state.get_room_version(&pdu.room_id)?;
|
||||
let room_version_id = services()
|
||||
.rooms
|
||||
.state
|
||||
.get_create_content::<ExtractVersion>(&pdu.room_id)?;
|
||||
pdu.redact(room_version_id, reason)?;
|
||||
|
||||
self.replace_pdu(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue