mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2025-09-30 18:42:05 +00:00
fix(hydra): Fix v11 room support
This commit is contained in:
parent
ff92573103
commit
35b7b45ea0
6 changed files with 73 additions and 44 deletions
|
@ -194,6 +194,7 @@ pub(crate) async fn create_room_route(
|
||||||
|
|
||||||
// 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 create_event_id = services
|
let create_event_id = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
|
@ -205,13 +206,13 @@ pub(crate) async fn create_room_route(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
sender_user,
|
sender_user,
|
||||||
None,
|
tmp_id,
|
||||||
&state_lock,
|
&state_lock,
|
||||||
)
|
)
|
||||||
.boxed()
|
.boxed()
|
||||||
.await?;
|
.await?;
|
||||||
trace!("Created room create event with ID {}", create_event_id);
|
trace!("Created room create event with ID {}", &create_event_id);
|
||||||
let room_id = match room_id {
|
let room_id = match room_id.clone() {
|
||||||
| Some(room_id) => room_id,
|
| Some(room_id) => room_id,
|
||||||
| None => {
|
| None => {
|
||||||
let as_room_id = create_event_id.as_str().replace('$', "!");
|
let as_room_id = create_event_id.as_str().replace('$', "!");
|
||||||
|
@ -287,6 +288,10 @@ pub(crate) async fn create_room_route(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
users.insert(sender_user.to_owned(), int!(100));
|
||||||
|
creators.clear(); // If this vec is not empty, default_power_levels_content will
|
||||||
|
// treat this as a v12 room
|
||||||
}
|
}
|
||||||
|
|
||||||
let power_levels_content = default_power_levels_content(
|
let power_levels_content = default_power_levels_content(
|
||||||
|
|
|
@ -587,6 +587,26 @@ where
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_creator<EV>(v: &RoomVersion, c: &BTreeSet<OwnedUserId>, ce: &EV, user_id: &UserId) -> bool
|
||||||
|
where
|
||||||
|
EV: Event + Send + Sync,
|
||||||
|
{
|
||||||
|
if v.explicitly_privilege_room_creators {
|
||||||
|
c.contains(user_id)
|
||||||
|
} else if v.use_room_create_sender {
|
||||||
|
ce.sender() == user_id
|
||||||
|
} else {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
let creator = from_json_str::<RoomCreateEventContent>(ce.content().get())
|
||||||
|
.unwrap()
|
||||||
|
.creator
|
||||||
|
.ok_or_else(|| serde_json::Error::missing_field("creator"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
creator == user_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO deserializing the member, power, join_rules event contents is done in
|
// TODO deserializing the member, power, join_rules event contents is done in
|
||||||
// conduit just before this is called. Could they be passed in?
|
// conduit just before this is called. Could they be passed in?
|
||||||
/// Does the user who sent this member event have required power levels to do
|
/// Does the user who sent this member event have required power levels to do
|
||||||
|
@ -618,9 +638,6 @@ where
|
||||||
E: Event + Send + Sync,
|
E: Event + Send + Sync,
|
||||||
for<'a> &'a E: Event + Send,
|
for<'a> &'a E: Event + Send,
|
||||||
{
|
{
|
||||||
fn is_creator(v: &RoomVersion, c: &BTreeSet<OwnedUserId>, user_id: &UserId) -> bool {
|
|
||||||
c.contains(user_id) && v.explicitly_privilege_room_creators
|
|
||||||
}
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct GetThirdPartyInvite {
|
struct GetThirdPartyInvite {
|
||||||
third_party_invite: Option<Raw<ThirdPartyInvite>>,
|
third_party_invite: Option<Raw<ThirdPartyInvite>>,
|
||||||
|
@ -677,6 +694,7 @@ where
|
||||||
target_power = Some(&Int::MAX);
|
target_power = Some(&Int::MAX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trace!(?creators, "creators for room");
|
||||||
|
|
||||||
let mut join_rules = JoinRule::Invite;
|
let mut join_rules = JoinRule::Invite;
|
||||||
if let Some(jr) = &join_rules_event {
|
if let Some(jr) = &join_rules_event {
|
||||||
|
@ -707,7 +725,7 @@ where
|
||||||
(int!(0), int!(0))
|
(int!(0), int!(0))
|
||||||
};
|
};
|
||||||
let user_joined = user_for_join_auth_membership == &MembershipState::Join;
|
let user_joined = user_for_join_auth_membership == &MembershipState::Join;
|
||||||
let okay_power = is_creator(room_version, &creators, user_for_join_auth)
|
let okay_power = is_creator(room_version, &creators, create_room, user_for_join_auth)
|
||||||
|| auth_user_pl >= invite_level;
|
|| auth_user_pl >= invite_level;
|
||||||
user_joined && okay_power
|
user_joined && okay_power
|
||||||
} else {
|
} else {
|
||||||
|
@ -715,8 +733,8 @@ where
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let sender_creator = is_creator(room_version, &creators, sender);
|
let sender_creator = is_creator(room_version, &creators, create_room, sender);
|
||||||
let target_creator = is_creator(room_version, &creators, target_user);
|
let target_creator = is_creator(room_version, &creators, create_room, target_user);
|
||||||
|
|
||||||
Ok(match target_membership {
|
Ok(match target_membership {
|
||||||
| MembershipState::Join => {
|
| MembershipState::Join => {
|
||||||
|
@ -732,15 +750,14 @@ where
|
||||||
let no_more_prev_events = prev_events.next().is_none();
|
let no_more_prev_events = prev_events.next().is_none();
|
||||||
|
|
||||||
if prev_event_is_create_event && no_more_prev_events {
|
if prev_event_is_create_event && no_more_prev_events {
|
||||||
trace!("checking if sender is a room creator for initial membership event");
|
trace!(
|
||||||
let is_creator = (sender_creator && target_creator) || {
|
sender = %sender,
|
||||||
#[allow(deprecated)]
|
target_user = %target_user,
|
||||||
let creator = from_json_str::<RoomCreateEventContent>(create_room.content().get())?
|
?sender_creator,
|
||||||
.creator
|
?target_creator,
|
||||||
.ok_or_else(|| serde_json::Error::missing_field("creator"))?;
|
"checking if sender is a room creator for initial membership event"
|
||||||
|
);
|
||||||
creator == sender && creator == target_user
|
let is_creator = sender_creator && target_creator;
|
||||||
};
|
|
||||||
|
|
||||||
if is_creator {
|
if is_creator {
|
||||||
debug!("sender is room creator, allowing join");
|
debug!("sender is room creator, allowing join");
|
||||||
|
|
|
@ -140,7 +140,7 @@ async fn migrate(services: &Services) -> Result<()> {
|
||||||
|
|
||||||
if services.globals.db.database_version().await < 18 {
|
if services.globals.db.database_version().await < 18 {
|
||||||
services.globals.db.bump_database_version(18);
|
services.globals.db.bump_database_version(18);
|
||||||
info!("Migration: Bumped database version to 18")
|
info!("Migration: Bumped database version to 18");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -196,7 +196,7 @@ async fn get_auth_chain_inner(
|
||||||
},
|
},
|
||||||
| Ok(pdu) => {
|
| Ok(pdu) => {
|
||||||
if let Some(claimed_room_id) = pdu.room_id.clone() {
|
if let Some(claimed_room_id) = pdu.room_id.clone() {
|
||||||
if claimed_room_id != room_id.to_owned() {
|
if claimed_room_id != *room_id {
|
||||||
return Err!(Request(Forbidden(error!(
|
return Err!(Request(Forbidden(error!(
|
||||||
?event_id,
|
?event_id,
|
||||||
?room_id,
|
?room_id,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashSet, iter::once};
|
use std::{collections::HashSet, iter::once};
|
||||||
|
|
||||||
use conduwuit::{RoomVersion, trace};
|
use conduwuit::trace;
|
||||||
use conduwuit_core::{
|
use conduwuit_core::{
|
||||||
Err, Result, implement,
|
Err, Result, implement,
|
||||||
matrix::{event::Event, pdu::PduBuilder},
|
matrix::{event::Event, pdu::PduBuilder},
|
||||||
|
@ -12,7 +12,6 @@ use ruma::{
|
||||||
events::{
|
events::{
|
||||||
TimelineEventType,
|
TimelineEventType,
|
||||||
room::{
|
room::{
|
||||||
create::RoomCreateEventContent,
|
|
||||||
member::{MembershipState, RoomMemberEventContent},
|
member::{MembershipState, RoomMemberEventContent},
|
||||||
redaction::RoomRedactionEventContent,
|
redaction::RoomRedactionEventContent,
|
||||||
},
|
},
|
||||||
|
@ -25,7 +24,7 @@ use super::RoomMutexGuard;
|
||||||
/// takes a roomid_mutex_state, meaning that only this function is able to
|
/// takes a roomid_mutex_state, meaning that only this function is able to
|
||||||
/// mutate the room state.
|
/// mutate the room state.
|
||||||
#[implement(super::Service)]
|
#[implement(super::Service)]
|
||||||
#[tracing::instrument(skip(self, state_lock), level = "trace")]
|
#[tracing::instrument(skip(self, state_lock, pdu_builder), level = "trace")]
|
||||||
pub async fn build_and_append_pdu(
|
pub async fn build_and_append_pdu(
|
||||||
&self,
|
&self,
|
||||||
pdu_builder: PduBuilder,
|
pdu_builder: PduBuilder,
|
||||||
|
@ -99,23 +98,19 @@ pub async fn build_and_append_pdu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if *pdu.kind() == TimelineEventType::RoomCreate {
|
if *pdu.kind() == TimelineEventType::RoomCreate {
|
||||||
trace!("Running room create checks for room {room_id}");
|
trace!("Creating shortroomid for {room_id}");
|
||||||
let content: RoomCreateEventContent = pdu.get_content()?;
|
|
||||||
let room_features = RoomVersion::new(&content.room_version)?;
|
|
||||||
if room_features.room_ids_as_hashes {
|
|
||||||
// bootstrap shortid for room
|
|
||||||
self.services
|
self.services
|
||||||
.short
|
.short
|
||||||
.get_or_create_shortroomid(&room_id)
|
.get_or_create_shortroomid(&room_id)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// We append to state before appending the pdu, so we don't have a moment in
|
// We append to state before appending the pdu, so we don't have a moment in
|
||||||
// time with the pdu without it's state. This is okay because append_pdu can't
|
// time with the pdu without it's state. This is okay because append_pdu can't
|
||||||
// fail.
|
// fail.
|
||||||
trace!("Appending {} state for room {room_id}", pdu.event_id());
|
trace!("Appending {} state for room {room_id}", pdu.event_id());
|
||||||
let statehashid = self.services.state.append_to_state(&pdu, &room_id).await?;
|
let statehashid = self.services.state.append_to_state(&pdu, &room_id).await?;
|
||||||
|
trace!("State hash ID for {room_id}: {statehashid:?}");
|
||||||
|
|
||||||
trace!("Generating raw ID for PDU {}", pdu.event_id());
|
trace!("Generating raw ID for PDU {}", pdu.event_id());
|
||||||
let pdu_id = self
|
let pdu_id = self
|
||||||
|
|
|
@ -57,18 +57,30 @@ pub async fn create_hash_and_sign_event(
|
||||||
timestamp,
|
timestamp,
|
||||||
} = pdu_builder;
|
} = pdu_builder;
|
||||||
// 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
|
||||||
|
trace!(
|
||||||
|
"Creating event of type {} in room {}",
|
||||||
|
event_type,
|
||||||
|
room_id.as_ref().map_or("None", |id| id.as_str())
|
||||||
|
);
|
||||||
let room_version_id = match room_id {
|
let room_version_id = match room_id {
|
||||||
| Some(room_id) => self
|
| Some(room_id) => {
|
||||||
.services
|
trace!(%room_id, "Looking up existing room ID");
|
||||||
|
self.services
|
||||||
.state
|
.state
|
||||||
.get_room_version(room_id)
|
.get_room_version(room_id)
|
||||||
.await
|
.await
|
||||||
.or_else(|_| from_evt(room_id.to_owned(), &event_type.clone(), &content.clone()))?,
|
.or_else(|_| {
|
||||||
| None => from_evt(
|
from_evt(room_id.to_owned(), &event_type.clone(), &content.clone())
|
||||||
|
})?
|
||||||
|
},
|
||||||
|
| None => {
|
||||||
|
trace!("No room ID, assuming room creation");
|
||||||
|
from_evt(
|
||||||
RoomId::new(self.services.globals.server_name()),
|
RoomId::new(self.services.globals.server_name()),
|
||||||
&event_type.clone(),
|
&event_type.clone(),
|
||||||
&content.clone(),
|
&content.clone(),
|
||||||
)?,
|
)?
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let room_version = RoomVersion::new(&room_version_id).expect("room version is supported");
|
let room_version = RoomVersion::new(&room_version_id).expect("room version is supported");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue