mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-07-08 06:30:01 +02:00
add support for MSC4168: migrate m.room.*
on room upgrades
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
2834d50ddf
commit
1d97858aa6
1 changed files with 94 additions and 29 deletions
|
@ -20,6 +20,7 @@ use ruma::{
|
||||||
tombstone::RoomTombstoneEventContent,
|
tombstone::RoomTombstoneEventContent,
|
||||||
topic::RoomTopicEventContent,
|
topic::RoomTopicEventContent,
|
||||||
},
|
},
|
||||||
|
space::child::SpaceChildEventContent,
|
||||||
StateEventType, TimelineEventType,
|
StateEventType, TimelineEventType,
|
||||||
},
|
},
|
||||||
int,
|
int,
|
||||||
|
@ -618,22 +619,14 @@ pub(crate) async fn upgrade_room_route(
|
||||||
V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => {
|
V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => {
|
||||||
create_event_content.insert(
|
create_event_content.insert(
|
||||||
"creator".into(),
|
"creator".into(),
|
||||||
json!(&sender_user).try_into().map_err(|e| {
|
json!(&sender_user)
|
||||||
info!("Error forming creation event: {e}");
|
.try_into()
|
||||||
Error::BadRequest(ErrorKind::BadJson, "Error forming creation event")
|
.map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
|
||||||
})?,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
V11 => {
|
|
||||||
// "creator" key no longer exists in V11 rooms
|
|
||||||
create_event_content.remove("creator");
|
|
||||||
},
|
|
||||||
_ => {
|
_ => {
|
||||||
warn!("Unexpected or unsupported room version {}", body.new_version);
|
// "creator" key no longer exists in V11+ rooms
|
||||||
return Err(Error::BadRequest(
|
create_event_content.remove("creator");
|
||||||
ErrorKind::BadJson,
|
|
||||||
"Unexpected or unsupported room version found",
|
|
||||||
));
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -642,26 +635,100 @@ pub(crate) async fn upgrade_room_route(
|
||||||
"room_version".into(),
|
"room_version".into(),
|
||||||
json!(&body.new_version)
|
json!(&body.new_version)
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Error forming creation event"))?,
|
.map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
|
||||||
);
|
);
|
||||||
create_event_content.insert(
|
create_event_content.insert(
|
||||||
"predecessor".into(),
|
"predecessor".into(),
|
||||||
json!(predecessor)
|
json!(predecessor)
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Error forming creation event"))?,
|
.map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Validate creation event content
|
// if the room was a space:
|
||||||
if serde_json::from_str::<CanonicalJsonObject>(
|
// - migrate m.space.child and/or m.space.parent
|
||||||
to_raw_value(&create_event_content)
|
// - add space type to replacement room m.room.create
|
||||||
.expect("Error forming creation event")
|
//
|
||||||
.get(),
|
// as apart of MSC4168
|
||||||
)
|
if services
|
||||||
.is_err()
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.get_room_type(&body.room_id)
|
||||||
|
.unwrap_or(None)
|
||||||
|
.is_some_and(|room_type| room_type == ruma::room::RoomType::Space)
|
||||||
{
|
{
|
||||||
return Err(Error::BadRequest(ErrorKind::BadJson, "Error forming creation event"));
|
create_event_content.insert(
|
||||||
|
"type".into(),
|
||||||
|
json!(ruma::room::RoomType::Space)
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| err!(Request(BadJson("Error forming creation event"))))?,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(event_content) = services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.room_state_get(&body.room_id, &StateEventType::SpaceChild, body.room_id.as_str())
|
||||||
|
.unwrap_or(None)
|
||||||
|
{
|
||||||
|
// space contents that are empty are not apart of the space
|
||||||
|
if !event_content.content.get().is_empty() {
|
||||||
|
// remove all but us from via
|
||||||
|
let mut new_content: SpaceChildEventContent = serde_json::from_str(event_content.content.get())
|
||||||
|
.map_err(|_| err!(Database(error!("Invalid m.space.child content in database"))))?;
|
||||||
|
new_content.via = vec![services.globals.config.server_name.clone()];
|
||||||
|
|
||||||
|
services
|
||||||
|
.rooms
|
||||||
|
.timeline
|
||||||
|
.build_and_append_pdu(
|
||||||
|
PduBuilder {
|
||||||
|
event_type: StateEventType::SpaceChild.to_string().into(),
|
||||||
|
content: to_raw_value(&new_content).expect("we just created it"),
|
||||||
|
unsigned: None,
|
||||||
|
state_key: Some(replacement_room.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
|
sender_user,
|
||||||
|
&replacement_room,
|
||||||
|
&state_lock,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(event_content) = services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.room_state_get(&body.room_id, &StateEventType::SpaceParent, body.room_id.as_str())
|
||||||
|
.unwrap_or(None)
|
||||||
|
{
|
||||||
|
// space contents that are empty are not apart of the space
|
||||||
|
if !event_content.content.get().is_empty() {
|
||||||
|
// remove all but us from via
|
||||||
|
let mut new_content: SpaceChildEventContent = serde_json::from_str(event_content.content.get())
|
||||||
|
.map_err(|_| err!(Database(error!("Invalid m.space.child content in database"))))?;
|
||||||
|
new_content.via = vec![services.globals.config.server_name.clone()];
|
||||||
|
|
||||||
|
services
|
||||||
|
.rooms
|
||||||
|
.timeline
|
||||||
|
.build_and_append_pdu(
|
||||||
|
PduBuilder {
|
||||||
|
event_type: StateEventType::SpaceParent.to_string().into(),
|
||||||
|
content: to_raw_value(&new_content).expect("we just created it"),
|
||||||
|
unsigned: None,
|
||||||
|
state_key: Some(replacement_room.to_string()),
|
||||||
|
redacts: None,
|
||||||
|
},
|
||||||
|
sender_user,
|
||||||
|
&replacement_room,
|
||||||
|
&state_lock,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m.room.create
|
||||||
services
|
services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
|
@ -755,11 +822,11 @@ pub(crate) async fn upgrade_room_route(
|
||||||
.rooms
|
.rooms
|
||||||
.state_accessor
|
.state_accessor
|
||||||
.room_state_get(&body.room_id, &StateEventType::RoomPowerLevels, "")?
|
.room_state_get(&body.room_id, &StateEventType::RoomPowerLevels, "")?
|
||||||
.ok_or_else(|| Error::bad_database("Found room without m.room.create event."))?
|
.ok_or_else(|| err!(Database(error!("Found room without m.room.create event."))))?
|
||||||
.content
|
.content
|
||||||
.get(),
|
.get(),
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::bad_database("Invalid room event in database."))?;
|
.map_err(|_| err!(Database(error!("Invalid room event in database."))))?;
|
||||||
|
|
||||||
// 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(
|
||||||
|
@ -767,9 +834,7 @@ pub(crate) async fn upgrade_room_route(
|
||||||
power_levels_event_content
|
power_levels_event_content
|
||||||
.users_default
|
.users_default
|
||||||
.checked_add(int!(1))
|
.checked_add(int!(1))
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| err!(Request(BadJson("users_default power levels event content is not valid"))))?,
|
||||||
Error::BadRequest(ErrorKind::BadJson, "users_default power levels event content is not valid")
|
|
||||||
})?,
|
|
||||||
);
|
);
|
||||||
power_levels_event_content.events_default = new_level;
|
power_levels_event_content.events_default = new_level;
|
||||||
power_levels_event_content.invite = new_level;
|
power_levels_event_content.invite = new_level;
|
||||||
|
@ -833,7 +898,7 @@ fn default_power_levels_content(
|
||||||
|
|
||||||
if let Some(power_level_content_override) = power_level_content_override {
|
if let Some(power_level_content_override) = power_level_content_override {
|
||||||
let json: JsonObject = serde_json::from_str(power_level_content_override.json().get())
|
let json: JsonObject = serde_json::from_str(power_level_content_override.json().get())
|
||||||
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid power_level_content_override."))?;
|
.map_err(|_| err!(Request(BadJson("Invalid power_level_content_override"))))?;
|
||||||
|
|
||||||
for (key, value) in json {
|
for (key, value) in json {
|
||||||
power_levels_content[key] = value;
|
power_levels_content[key] = value;
|
||||||
|
|
Loading…
Add table
Reference in a new issue