refactor: Fix errors in api/client/room/

This commit is contained in:
Ginger
2026-04-28 09:16:51 -04:00
parent 97a01a1500
commit a2f6141f4b
6 changed files with 181 additions and 135 deletions
+1 -1
View File
@@ -259,7 +259,7 @@ pub(crate) async fn invite_helper(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder::state(recipient_user.to_string(), &content), PartialPdu::state(recipient_user.to_string(), &content),
sender_user, sender_user,
Some(room_id), Some(room_id),
&state_lock, &state_lock,
+47 -16
View File
@@ -9,8 +9,10 @@ use conduwuit::{
use conduwuit_service::{Services, appservice::RegistrationInfo}; use conduwuit_service::{Services, appservice::RegistrationInfo};
use futures::FutureExt; use futures::FutureExt;
use ruma::{ use ruma::{
CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId, CanonicalJsonObject, Int, MilliSecondsSinceUnixEpoch, OwnedRoomAliasId, OwnedRoomId,
OwnedUserId, RoomAliasId, RoomId, RoomVersionId, UserId,
api::client::room::{self, create_room}, api::client::room::{self, create_room},
assign,
events::{ events::{
TimelineEventType, TimelineEventType,
room::{ room::{
@@ -26,7 +28,7 @@ use ruma::{
}, },
}, },
int, int,
room_version_rules::RoomIdFormatVersion, room_version_rules::{AuthorizationRules, RoomIdFormatVersion},
serde::{JsonObject, Raw}, serde::{JsonObject, Raw},
}; };
use ruminuwuity::invite_permission_config::FilterLevel; use ruminuwuity::invite_permission_config::FilterLevel;
@@ -214,18 +216,33 @@ pub(crate) async fn create_room_route(
.short .short
.get_or_create_shortroomid(&room_id) .get_or_create_shortroomid(&room_id)
.await; .await;
services.rooms.state.mutex.lock(&room_id).await services.rooms.state.mutex.lock(room_id.as_str()).await
}, },
| None => { | None => {
let temp_room_id = RoomId::new(services.globals.server_name()); let temp_room_id = RoomId::new_v1(services.globals.server_name());
trace!("Locking temporary room state mutex for {temp_room_id}"); trace!("Locking temporary room state mutex for {temp_room_id}");
services.rooms.state.mutex.lock(&temp_room_id).await services.rooms.state.mutex.lock(temp_room_id.as_str()).await
}, },
}; };
// 1. The room create event // 1. The room create event
debug!("Creating room create event for {sender_user} in room {room_id:?}"); debug!("Creating room create event for {sender_user} in room {room_id:?}");
let tmp_id = room_id.as_deref(); let tmp_id = room_id.as_deref();
// Allow requesters to override the `origin_server_ts` to customize room ids
// from v12 onwards
let custom_origin_server_ts = body
.json_body
.as_ref()
.unwrap()
.as_object()
.unwrap()
.get("origin_server_ts")
.and_then(|value| value.as_integer())
.map(|value| value.into())
.and_then(|value: i64| value.try_into().ok())
.map(MilliSecondsSinceUnixEpoch);
let create_event_id = services let create_event_id = services
.rooms .rooms
.timeline .timeline
@@ -234,7 +251,7 @@ pub(crate) async fn create_room_route(
event_type: TimelineEventType::RoomCreate, event_type: TimelineEventType::RoomCreate,
content: to_raw_value(&create_content)?, content: to_raw_value(&create_content)?,
state_key: Some(StateKey::new()), state_key: Some(StateKey::new()),
timestamp: body.origin_server_ts, timestamp: custom_origin_server_ts,
..Default::default() ..Default::default()
}, },
sender_user, sender_user,
@@ -295,7 +312,10 @@ pub(crate) async fn create_room_route(
let mut creators: Vec<OwnedUserId> = vec![sender_user.to_owned()]; let mut creators: Vec<OwnedUserId> = vec![sender_user.to_owned()];
// Do we care about additional_creators? // Do we care about additional_creators?
if room_version_rules.explicitly_privilege_room_creators { if room_version_rules
.authorization
.explicitly_privilege_room_creators
{
// Have they been specified? // Have they been specified?
if let Some(additional_creators) = create_content.get("additional_creators") { if let Some(additional_creators) = create_content.get("additional_creators") {
// Are they a real array? // Are they a real array?
@@ -305,9 +325,9 @@ pub(crate) async fn create_room_route(
// Are they a string? // Are they a string?
if let Some(creator) = creator.as_str() { if let Some(creator) = creator.as_str() {
// Do they parse into a real user ID? // Do they parse into a real user ID?
if let Ok(creator) = OwnedUserId::parse(creator) { if let Ok(creator) = UserId::parse(creator) {
// Add them to the power levels and creators // Add them to the power levels and creators
creators.push(creator.clone()); creators.push(creator);
} }
} }
} }
@@ -320,10 +340,13 @@ pub(crate) async fn create_room_route(
} }
let power_levels_content = default_power_levels_content( let power_levels_content = default_power_levels_content(
body.power_level_content_override.as_ref(), body.power_level_content_override
.as_ref()
.map(|power_levels| power_levels.cast_ref()),
&body.visibility, &body.visibility,
power_levels_to_grant, power_levels_to_grant,
creators, creators,
&room_version_rules.authorization,
)?; )?;
services services
@@ -349,10 +372,13 @@ pub(crate) async fn create_room_route(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PartialPdu::state(String::new(), &RoomCanonicalAliasEventContent { PartialPdu::state(
String::new(),
&assign!(RoomCanonicalAliasEventContent::new(), {
alias: Some(room_alias_id.to_owned()), alias: Some(room_alias_id.to_owned()),
alt_aliases: vec![], alt_aliases: vec![],
}), }),
),
sender_user, sender_user,
Some(&room_id), Some(&room_id),
&state_lock, &state_lock,
@@ -420,7 +446,9 @@ pub(crate) async fn create_room_route(
// 6. Events listed in initial_state // 6. Events listed in initial_state
for event in &body.initial_state { for event in &body.initial_state {
let mut partial_pdu = event.deserialize_as::<PartialPdu>().map_err(|e| { let mut partial_pdu = event
.deserialize_as_unchecked::<PartialPdu>()
.map_err(|e| {
err!(Request(InvalidParam(warn!("Invalid initial state event: {e:?}")))) err!(Request(InvalidParam(warn!("Invalid initial state event: {e:?}"))))
})?; })?;
@@ -473,7 +501,7 @@ pub(crate) async fn create_room_route(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PartialPdu::state(String::new(), &RoomTopicEventContent { topic: topic.clone() }), PartialPdu::state(String::new(), &RoomTopicEventContent::new(topic.clone())),
sender_user, sender_user,
Some(&room_id), Some(&room_id),
&state_lock, &state_lock,
@@ -528,10 +556,13 @@ fn default_power_levels_content(
visibility: &room::Visibility, visibility: &room::Visibility,
users: BTreeMap<OwnedUserId, Int>, users: BTreeMap<OwnedUserId, Int>,
creators: Vec<OwnedUserId>, creators: Vec<OwnedUserId>,
authorization_rules: &AuthorizationRules,
) -> Result<serde_json::Value> { ) -> Result<serde_json::Value> {
let mut power_levels_content = let mut power_levels_content =
serde_json::to_value(RoomPowerLevelsEventContent { users, ..Default::default() }) serde_json::to_value(assign!(RoomPowerLevelsEventContent::new(authorization_rules), {
.expect("event is valid, we just created it"); users
}))
.unwrap();
// secure proper defaults of sensitive/dangerous permissions that moderators // secure proper defaults of sensitive/dangerous permissions that moderators
// (power level 50) should not have easy access to // (power level 50) should not have easy access to
@@ -621,7 +652,7 @@ async fn room_alias_check(
} }
let server_name = services.globals.server_name(); let server_name = services.globals.server_name();
let full_room_alias = OwnedRoomAliasId::parse(format!("#{room_alias_name}:{server_name}")) let full_room_alias = RoomAliasId::parse(format!("#{room_alias_name}:{server_name}"))
.map_err(|e| { .map_err(|e| {
err!(Request(InvalidParam(debug_error!( err!(Request(InvalidParam(debug_error!(
?e, ?e,
+1 -1
View File
@@ -44,5 +44,5 @@ pub(crate) async fn get_room_event_route(
event.set_unsigned(body.sender_user.as_deref()); event.set_unsigned(body.sender_user.as_deref());
Ok(get_room_event::v3::Response { event: event.into_format() }) Ok(get_room_event::v3::Response::new(event.into_format()))
} }
+14 -13
View File
@@ -4,7 +4,10 @@ use conduwuit::{
utils::{BoolExt, stream::TryTools}, utils::{BoolExt, stream::TryTools},
}; };
use futures::{FutureExt, TryStreamExt, future::try_join4}; use futures::{FutureExt, TryStreamExt, future::try_join4};
use ruma::api::client::room::initial_sync::v3::{PaginationChunk, Request, Response}; use ruma::{
api::client::peeking::get_current_state::v3::{PaginationChunk, Request, Response},
assign,
};
use crate::Ruma; use crate::Ruma;
@@ -69,29 +72,27 @@ pub(crate) async fn room_initial_sync_route(
.boxed() .boxed()
.await?; .await?;
let messages = PaginationChunk { let end = events
start: events.last().map(at!(0)).as_ref().map(ToString::to_string),
end: events
.first() .first()
.map(at!(0)) .map(at!(0))
.as_ref() .as_ref()
.map(ToString::to_string) .map(ToString::to_string)
.unwrap_or_default(), .unwrap_or_default();
let start = events.last().map(at!(0)).as_ref().map(ToString::to_string);
chunk: events let chunk = events
.into_iter() .into_iter()
.map(at!(1)) .map(at!(1))
.map(Event::into_format) .map(Event::into_format)
.collect(), .collect();
};
Ok(Response { let messages = assign!(PaginationChunk::new(chunk, end), { start });
room_id: room_id.to_owned(),
account_data: None, Ok(assign!(Response::new(room_id.to_owned()), {
account_data: vec![],
state: state.into(), state: state.into(),
messages: messages.chunk.is_empty().or_some(messages), messages: messages.chunk.is_empty().or_some(messages),
visibility: visibility.into(), visibility: visibility.into(),
membership, membership,
}) }))
} }
+102 -87
View File
@@ -2,16 +2,18 @@ use std::cmp::max;
use axum::extract::State; use axum::extract::State;
use conduwuit::{ use conduwuit::{
Err, Error, Event, Result, RoomVersion, debug, err, info, Err, Error, Event, Result, debug, err, info,
matrix::{StateKey, pdu::PartialPdu}, matrix::{StateKey, pdu::PartialPdu},
}; };
use futures::{FutureExt, StreamExt}; use futures::{FutureExt, StreamExt};
use ruma::{ use ruma::{
CanonicalJsonObject, RoomId, RoomVersionId, CanonicalJsonObject, RoomId, RoomVersionId,
api::client::{error::ErrorKind, room::upgrade_room}, api::{client::room::upgrade_room, error::ErrorKind},
assign,
events::{ events::{
StateEventType, TimelineEventType, StateEventType, TimelineEventType,
room::{ room::{
create::PreviousRoom,
member::{MembershipState, RoomMemberEventContent}, member::{MembershipState, RoomMemberEventContent},
power_levels::RoomPowerLevelsEventContent, power_levels::RoomPowerLevelsEventContent,
tombstone::RoomTombstoneEventContent, tombstone::RoomTombstoneEventContent,
@@ -19,6 +21,7 @@ use ruma::{
space::child::{RedactedSpaceChildEventContent, SpaceChildEventContent}, space::child::{RedactedSpaceChildEventContent, SpaceChildEventContent},
}, },
int, int,
room_version_rules::RoomIdFormatVersion,
}; };
use serde_json::{json, value::to_raw_value}; use serde_json::{json, value::to_raw_value};
@@ -76,7 +79,7 @@ pub(crate) async fn upgrade_room_route(
// First, check if the user has permission to upgrade the room (send tombstone // First, check if the user has permission to upgrade the room (send tombstone
// event) // event)
let old_room_state_lock = services.rooms.state.mutex.lock(&body.room_id).await; let old_room_state_lock = services.rooms.state.mutex.lock(body.room_id.as_str()).await;
// Check tombstone permission by attempting to create (but not send) the event // Check tombstone permission by attempting to create (but not send) the event
// Note that this does internally call the policy server with a fake room ID, // Note that this does internally call the policy server with a fake room ID,
@@ -85,10 +88,13 @@ pub(crate) async fn upgrade_room_route(
.rooms .rooms
.timeline .timeline
.create_hash_and_sign_event( .create_hash_and_sign_event(
PartialPdu::state(StateKey::new(), &RoomTombstoneEventContent { PartialPdu::state(
body: "This room has been replaced".to_owned(), StateKey::new(),
replacement_room: RoomId::new(services.globals.server_name()), &RoomTombstoneEventContent::new(
}), String::new(),
RoomId::new_v1(services.globals.server_name()),
),
),
sender_user, sender_user,
Some(&body.room_id), Some(&body.room_id),
&old_room_state_lock, &old_room_state_lock,
@@ -102,16 +108,19 @@ pub(crate) async fn upgrade_room_route(
drop(old_room_state_lock); drop(old_room_state_lock);
// Create a replacement room // Create a replacement room
let room_features = RoomVersion::new(&body.new_version)?; let room_version_rules = body
let replacement_room_owned = if !room_features.room_ids_as_hashes { .new_version
Some(RoomId::new(services.globals.server_name())) .rules()
.expect("new room version should have defined rules");
let replacement_room_owned = if room_version_rules.room_id_format == RoomIdFormatVersion::V2 {
Some(RoomId::new_v1(services.globals.server_name()))
} else { } else {
None None
}; };
let replacement_room: Option<&RoomId> = replacement_room_owned.as_ref().map(AsRef::as_ref); let replacement_room: Option<&RoomId> = replacement_room_owned.as_ref().map(AsRef::as_ref);
let replacement_room_tmp = match replacement_room { let replacement_room_tmp = match replacement_room {
| Some(v) => v, | Some(v) => v,
| None => &RoomId::new(services.globals.server_name()), | None => &RoomId::new_v1(services.globals.server_name()),
}; };
let _short_id = services let _short_id = services
@@ -121,18 +130,21 @@ pub(crate) async fn upgrade_room_route(
.await; .await;
// For pre-v12 rooms, send tombstone before creating replacement room // For pre-v12 rooms, send tombstone before creating replacement room
let tombstone_event_id = if !room_features.room_ids_as_hashes { let tombstone_event_id = if room_version_rules.room_id_format != RoomIdFormatVersion::V2 {
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await; let state_lock = services.rooms.state.mutex.lock(body.room_id.as_str()).await;
// Send a m.room.tombstone event to the old room to indicate that it is not // Send a m.room.tombstone event to the old room to indicate that it is not
// intended to be used any further // intended to be used any further
let tombstone_event_id = services let tombstone_event_id = services
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder::state(StateKey::new(), &RoomTombstoneEventContent { PartialPdu::state(
body: "This room has been replaced".to_owned(), StateKey::new(),
replacement_room: replacement_room.unwrap().to_owned(), &RoomTombstoneEventContent::new(
}), "This room has been replaced".to_owned(),
replacement_room.unwrap().to_owned(),
),
),
sender_user, sender_user,
Some(&body.room_id), Some(&body.room_id),
&state_lock, &state_lock,
@@ -145,7 +157,12 @@ pub(crate) async fn upgrade_room_route(
} else { } else {
None None
}; };
let state_lock = services.rooms.state.mutex.lock(replacement_room_tmp).await; let state_lock = services
.rooms
.state
.mutex
.lock(replacement_room_tmp.as_str())
.await;
// Get the old room creation event // Get the old room creation event
let mut create_event_content: CanonicalJsonObject = services let mut create_event_content: CanonicalJsonObject = services
@@ -156,10 +173,13 @@ pub(crate) async fn upgrade_room_route(
.map_err(|_| err!(Database("Found room without m.room.create event.")))?; .map_err(|_| err!(Database("Found room without m.room.create event.")))?;
// Use the m.room.tombstone event as the predecessor // Use the m.room.tombstone event as the predecessor
let predecessor = Some(ruma::events::room::create::PreviousRoom::new(
body.room_id.clone(), let predecessor = {
tombstone_event_id, #[allow(deprecated, reason = "Clients still use event_id even though it's deprecated")]
)); Some(assign!(PreviousRoom::new(body.room_id.clone()), {
event_id: tombstone_event_id,
}))
};
// Send a m.room.create event containing a predecessor field and the applicable // Send a m.room.create event containing a predecessor field and the applicable
// room_version // room_version
@@ -211,7 +231,7 @@ pub(crate) async fn upgrade_room_route(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PartialPdu {
event_type: TimelineEventType::RoomCreate, event_type: TimelineEventType::RoomCreate,
content: to_raw_value(&create_event_content) content: to_raw_value(&create_event_content)
.expect("event is valid, we just created it"), .expect("event is valid, we just created it"),
@@ -227,11 +247,18 @@ pub(crate) async fn upgrade_room_route(
.boxed() .boxed()
.await?; .await?;
let create_id = create_event_id.as_str().replace('$', "!"); let create_id = create_event_id.as_str().replace('$', "!");
let (replacement_room, state_lock) = if room_features.room_ids_as_hashes { let (replacement_room, state_lock) =
if room_version_rules.room_id_format == RoomIdFormatVersion::V2 {
let parsed_room_id = RoomId::parse(&create_id)?; let parsed_room_id = RoomId::parse(&create_id)?;
(Some(parsed_room_id), services.rooms.state.mutex.lock(parsed_room_id).await) let lock = services
.rooms
.state
.mutex
.lock(parsed_room_id.as_str())
.await;
(Some(parsed_room_id), lock)
} else { } else {
(replacement_room, state_lock) (replacement_room.map(ToOwned::to_owned), state_lock)
}; };
// Join the new room // Join the new room
@@ -239,27 +266,16 @@ pub(crate) async fn upgrade_room_route(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PartialPdu::state(
event_type: TimelineEventType::RoomMember, sender_user.as_str(),
content: to_raw_value(&RoomMemberEventContent { &assign!(RoomMemberEventContent::new(MembershipState::Join), {
membership: MembershipState::Join,
displayname: services.users.displayname(sender_user).await.ok(), displayname: services.users.displayname(sender_user).await.ok(),
avatar_url: services.users.avatar_url(sender_user).await.ok(), avatar_url: services.users.avatar_url(sender_user).await.ok(),
is_direct: None,
third_party_invite: None,
blurhash: services.users.blurhash(sender_user).await.ok(), blurhash: services.users.blurhash(sender_user).await.ok(),
reason: None, }),
join_authorized_via_users_server: None, ),
redact_events: None,
})
.expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(sender_user.as_str().into()),
redacts: None,
timestamp: None,
},
sender_user, sender_user,
replacement_room, replacement_room.as_deref(),
&state_lock, &state_lock,
) )
.boxed() .boxed()
@@ -306,14 +322,14 @@ pub(crate) async fn upgrade_room_route(
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PartialPdu {
event_type: event_type.to_string().into(), event_type: event_type.to_string().into(),
content: event_content, content: event_content,
state_key: Some(StateKey::from(state_key)), state_key: Some(StateKey::from(state_key)),
..Default::default() ..Default::default()
}, },
sender_user, sender_user,
replacement_room, replacement_room.as_deref(),
&state_lock, &state_lock,
) )
.boxed() .boxed()
@@ -332,27 +348,27 @@ pub(crate) async fn upgrade_room_route(
services services
.rooms .rooms
.alias .alias
.remove_alias(alias, sender_user) .remove_alias(&alias, sender_user)
.await?; .await?;
services services.rooms.alias.set_alias(
.rooms &alias,
.alias replacement_room.as_ref().unwrap(),
.set_alias(alias, replacement_room.unwrap(), sender_user)?; sender_user,
)?;
} }
// Get the old room power levels // Get the old room power levels
let power_levels_event_content: RoomPowerLevelsEventContent = services let mut power_levels = services
.rooms .rooms
.state_accessor .state_accessor
.room_state_get_content(&body.room_id, &StateEventType::RoomPowerLevels, "") .get_room_power_levels(&body.room_id)
.await .await;
.map_err(|_| err!(Database("Found room without m.room.power_levels event.")))?;
// Setting events_default and invite to the greater of 50 and users_default + 1 // Setting events_default and invite to the greater of 50 and users_default + 1
let new_level = max( let new_level = max(
int!(50), int!(50),
power_levels_event_content power_levels
.users_default .users_default
.checked_add(int!(1)) .checked_add(int!(1))
.ok_or_else(|| { .ok_or_else(|| {
@@ -360,17 +376,19 @@ pub(crate) async fn upgrade_room_route(
})?, })?,
); );
power_levels.events_default = new_level;
power_levels.invite = new_level;
// Modify the power levels in the old room to prevent sending of events and // Modify the power levels in the old room to prevent sending of events and
// inviting new users // inviting new users
services services
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder::state(StateKey::new(), &RoomPowerLevelsEventContent { PartialPdu::state(
events_default: new_level, StateKey::new(),
invite: new_level, &RoomPowerLevelsEventContent::try_from(power_levels).unwrap(),
..power_levels_event_content ),
}),
sender_user, sender_user,
Some(&body.room_id), Some(&body.room_id),
&state_lock, &state_lock,
@@ -381,18 +399,21 @@ pub(crate) async fn upgrade_room_route(
drop(state_lock); drop(state_lock);
// For v12 rooms, send tombstone AFTER creating replacement room // For v12 rooms, send tombstone AFTER creating replacement room
if room_features.room_ids_as_hashes { if room_version_rules.room_id_format == RoomIdFormatVersion::V2 {
let old_room_state_lock = services.rooms.state.mutex.lock(&body.room_id).await; let old_room_state_lock = services.rooms.state.mutex.lock(body.room_id.as_str()).await;
// For v12 rooms, no event reference in predecessor due to cyclic dependency - // For v12 rooms, no event reference in predecessor due to cyclic dependency -
// could best effort one maybe? // could best effort one maybe?
services services
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder::state(StateKey::new(), &RoomTombstoneEventContent { PartialPdu::state(
body: "This room has been replaced".to_owned(), StateKey::new(),
replacement_room: replacement_room.unwrap().to_owned(), &RoomTombstoneEventContent::new(
}), "This room has been replaced".to_owned(),
replacement_room.as_ref().unwrap().to_owned(),
),
),
sender_user, sender_user,
Some(&body.room_id), Some(&body.room_id),
&old_room_state_lock, &old_room_state_lock,
@@ -415,7 +436,7 @@ pub(crate) async fn upgrade_room_route(
.rooms .rooms
.state_accessor .state_accessor
.room_state_get_content::<SpaceChildEventContent>( .room_state_get_content::<SpaceChildEventContent>(
space_id, &space_id,
&StateEventType::SpaceChild, &StateEventType::SpaceChild,
body.room_id.as_str(), body.room_id.as_str(),
) )
@@ -427,24 +448,24 @@ pub(crate) async fn upgrade_room_route(
debug!( debug!(
"Updating space {space_id} child event for room {} to {}", "Updating space {space_id} child event for room {} to {}",
&body.room_id, &body.room_id,
replacement_room.unwrap() replacement_room.as_ref().unwrap()
); );
// First, drop the space's child event // First, drop the space's child event
let state_lock = services.rooms.state.mutex.lock(space_id).await; let state_lock = services.rooms.state.mutex.lock(space_id.as_str()).await;
debug!("Removing space child event for room {} in space {space_id}", &body.room_id); debug!("Removing space child event for room {} in space {space_id}", &body.room_id);
services services
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PartialPdu {
event_type: StateEventType::SpaceChild.into(), event_type: StateEventType::SpaceChild.into(),
content: to_raw_value(&RedactedSpaceChildEventContent {}) content: to_raw_value(&RedactedSpaceChildEventContent::new())
.expect("event is valid, we just created it"), .expect("event is valid, we just created it"),
state_key: Some(body.room_id.clone().as_str().into()), state_key: Some(body.room_id.clone().as_str().into()),
..Default::default() ..Default::default()
}, },
sender_user, sender_user,
Some(space_id), Some(&space_id),
&state_lock, &state_lock,
) )
.boxed() .boxed()
@@ -453,25 +474,21 @@ pub(crate) async fn upgrade_room_route(
// Now, add a new child event for the replacement room // Now, add a new child event for the replacement room
debug!( debug!(
"Adding space child event for room {} in space {space_id}", "Adding space child event for room {} in space {space_id}",
replacement_room.unwrap() replacement_room.as_ref().unwrap()
); );
services services
.rooms .rooms
.timeline .timeline
.build_and_append_pdu( .build_and_append_pdu(
PduBuilder { PartialPdu::state(
event_type: StateEventType::SpaceChild.into(), replacement_room.as_ref().unwrap().as_str(),
content: to_raw_value(&SpaceChildEventContent { &assign!(SpaceChildEventContent::new(vec![sender_user.server_name().to_owned()]), {
via: vec![sender_user.server_name().to_owned()],
order: child.order, order: child.order,
suggested: child.suggested, suggested: child.suggested,
}) }),
.expect("event is valid, we just created it"), ),
state_key: Some(replacement_room.unwrap().as_str().into()),
..Default::default()
},
sender_user, sender_user,
Some(space_id), Some(&space_id),
&state_lock, &state_lock,
) )
.boxed() .boxed()
@@ -480,13 +497,11 @@ pub(crate) async fn upgrade_room_route(
debug!( debug!(
"Finished updating space {space_id} child event for room {} to {}", "Finished updating space {space_id} child event for room {} to {}",
&body.room_id, &body.room_id,
replacement_room.unwrap() replacement_room.as_ref().unwrap()
); );
drop(state_lock); drop(state_lock);
} }
// Return the replacement room id // Return the replacement room id
Ok(upgrade_room::v3::Response { Ok(upgrade_room::v3::Response::new(replacement_room.as_ref().unwrap().to_owned()))
replacement_room: replacement_room.unwrap().to_owned(),
})
} }
+2 -3
View File
@@ -4,7 +4,6 @@ use ruma::{
events::{ events::{
StateEventType, TimelineEventType, StateEventType, TimelineEventType,
room::{ room::{
create::RoomCreateEventContent,
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent}, history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
member::{MembershipState, RoomMemberEventContent}, member::{MembershipState, RoomMemberEventContent},
}, },
@@ -64,7 +63,7 @@ pub async fn user_can_redact(
return Ok(is_own_event); return Ok(is_own_event);
} }
return Ok(false); Ok(false)
} }
/// Whether a user is allowed to see an event, based on /// Whether a user is allowed to see an event, based on
@@ -139,7 +138,7 @@ pub async fn user_can_invite(
self.services self.services
.timeline .timeline
.create_hash_and_sign_event( .create_hash_and_sign_event(
PduBuilder::state( PartialPdu::state(
target_user.as_str(), target_user.as_str(),
&RoomMemberEventContent::new(MembershipState::Invite), &RoomMemberEventContent::new(MembershipState::Invite),
), ),