diff --git a/src/api/client/room/create.rs b/src/api/client/room/create.rs index adf69568..efde40dd 100644 --- a/src/api/client/room/create.rs +++ b/src/api/client/room/create.rs @@ -194,6 +194,7 @@ pub(crate) async fn create_room_route( // 1. The room create event debug!("Creating room create event for {sender_user} in room {room_id:?}"); + let tmp_id = room_id.as_deref(); let create_event_id = services .rooms .timeline @@ -205,13 +206,13 @@ pub(crate) async fn create_room_route( ..Default::default() }, sender_user, - None, + tmp_id, &state_lock, ) .boxed() .await?; - trace!("Created room create event with ID {}", create_event_id); - let room_id = match room_id { + trace!("Created room create event with ID {}", &create_event_id); + let room_id = match room_id.clone() { | Some(room_id) => room_id, | None => { 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( diff --git a/src/core/matrix/state_res/event_auth.rs b/src/core/matrix/state_res/event_auth.rs index 12929278..9f5c4fed 100644 --- a/src/core/matrix/state_res/event_auth.rs +++ b/src/core/matrix/state_res/event_auth.rs @@ -587,6 +587,26 @@ where Ok(true) } +fn is_creator(v: &RoomVersion, c: &BTreeSet, 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::(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 // 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 @@ -618,9 +638,6 @@ where E: Event + Send + Sync, for<'a> &'a E: Event + Send, { - fn is_creator(v: &RoomVersion, c: &BTreeSet, user_id: &UserId) -> bool { - c.contains(user_id) && v.explicitly_privilege_room_creators - } #[derive(Deserialize)] struct GetThirdPartyInvite { third_party_invite: Option>, @@ -677,6 +694,7 @@ where target_power = Some(&Int::MAX); } } + trace!(?creators, "creators for room"); let mut join_rules = JoinRule::Invite; if let Some(jr) = &join_rules_event { @@ -707,7 +725,7 @@ where (int!(0), int!(0)) }; 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; user_joined && okay_power } else { @@ -715,8 +733,8 @@ where false }; - let sender_creator = is_creator(room_version, &creators, sender); - let target_creator = is_creator(room_version, &creators, target_user); + let sender_creator = is_creator(room_version, &creators, create_room, sender); + let target_creator = is_creator(room_version, &creators, create_room, target_user); Ok(match target_membership { | MembershipState::Join => { @@ -732,15 +750,14 @@ where let no_more_prev_events = prev_events.next().is_none(); if prev_event_is_create_event && no_more_prev_events { - trace!("checking if sender is a room creator for initial membership event"); - let is_creator = (sender_creator && target_creator) || { - #[allow(deprecated)] - let creator = from_json_str::(create_room.content().get())? - .creator - .ok_or_else(|| serde_json::Error::missing_field("creator"))?; - - creator == sender && creator == target_user - }; + trace!( + sender = %sender, + target_user = %target_user, + ?sender_creator, + ?target_creator, + "checking if sender is a room creator for initial membership event" + ); + let is_creator = sender_creator && target_creator; if is_creator { debug!("sender is room creator, allowing join"); diff --git a/src/service/migrations.rs b/src/service/migrations.rs index 4754058b..e604ebfd 100644 --- a/src/service/migrations.rs +++ b/src/service/migrations.rs @@ -140,7 +140,7 @@ async fn migrate(services: &Services) -> Result<()> { if services.globals.db.database_version().await < 18 { services.globals.db.bump_database_version(18); - info!("Migration: Bumped database version to 18") + info!("Migration: Bumped database version to 18"); } assert_eq!( diff --git a/src/service/rooms/auth_chain/mod.rs b/src/service/rooms/auth_chain/mod.rs index 7a31c946..28669848 100644 --- a/src/service/rooms/auth_chain/mod.rs +++ b/src/service/rooms/auth_chain/mod.rs @@ -196,7 +196,7 @@ async fn get_auth_chain_inner( }, | Ok(pdu) => { 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!( ?event_id, ?room_id, diff --git a/src/service/rooms/timeline/build.rs b/src/service/rooms/timeline/build.rs index 8c34e64c..741769af 100644 --- a/src/service/rooms/timeline/build.rs +++ b/src/service/rooms/timeline/build.rs @@ -1,6 +1,6 @@ use std::{collections::HashSet, iter::once}; -use conduwuit::{RoomVersion, trace}; +use conduwuit::trace; use conduwuit_core::{ Err, Result, implement, matrix::{event::Event, pdu::PduBuilder}, @@ -12,7 +12,6 @@ use ruma::{ events::{ TimelineEventType, room::{ - create::RoomCreateEventContent, member::{MembershipState, RoomMemberEventContent}, redaction::RoomRedactionEventContent, }, @@ -25,7 +24,7 @@ use super::RoomMutexGuard; /// takes a roomid_mutex_state, meaning that only this function is able to /// mutate the room state. #[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( &self, pdu_builder: PduBuilder, @@ -99,16 +98,11 @@ pub async fn build_and_append_pdu( } } if *pdu.kind() == TimelineEventType::RoomCreate { - trace!("Running room create checks for room {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 - .short - .get_or_create_shortroomid(&room_id) - .await; - } + trace!("Creating shortroomid for {room_id}"); + self.services + .short + .get_or_create_shortroomid(&room_id) + .await; } // We append to state before appending the pdu, so we don't have a moment in @@ -116,6 +110,7 @@ pub async fn build_and_append_pdu( // fail. trace!("Appending {} state for room {room_id}", pdu.event_id()); 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()); let pdu_id = self diff --git a/src/service/rooms/timeline/create.rs b/src/service/rooms/timeline/create.rs index c161a23a..31046680 100644 --- a/src/service/rooms/timeline/create.rs +++ b/src/service/rooms/timeline/create.rs @@ -57,18 +57,30 @@ pub async fn create_hash_and_sign_event( timestamp, } = pdu_builder; // 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 { - | Some(room_id) => self - .services - .state - .get_room_version(room_id) - .await - .or_else(|_| from_evt(room_id.to_owned(), &event_type.clone(), &content.clone()))?, - | None => from_evt( - RoomId::new(self.services.globals.server_name()), - &event_type.clone(), - &content.clone(), - )?, + | Some(room_id) => { + trace!(%room_id, "Looking up existing room ID"); + self.services + .state + .get_room_version(room_id) + .await + .or_else(|_| { + 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()), + &event_type.clone(), + &content.clone(), + )? + }, }; let room_version = RoomVersion::new(&room_version_id).expect("room version is supported");