Compare commits

...

3 Commits

Author SHA1 Message Date
Ginger 83963b5dba fix: Code cleanup 2026-01-08 20:00:59 -05:00
timedout a084575ad2 chore: Add news fragment 2026-01-09 00:47:44 +00:00
timedout 0da9465a0a fix: Creators can always publish to room dir 2026-01-09 00:29:40 +00:00
2 changed files with 38 additions and 20 deletions
+1
View File
@@ -0,0 +1 @@
Fixed room creators (in v12 rooms) being unable to publish rooms to the room directory. Contributed by @nex.
+37 -20
View File
@@ -1,7 +1,7 @@
use axum::extract::State; use axum::extract::State;
use axum_client_ip::InsecureClientIp; use axum_client_ip::InsecureClientIp;
use conduwuit::{ use conduwuit::{
Err, Event, Result, err, info, Err, Event, Result, RoomVersion, err, info,
utils::{ utils::{
TryFutureExtExt, TryFutureExtExt,
math::Expected, math::Expected,
@@ -30,6 +30,7 @@ use ruma::{
events::{ events::{
StateEventType, StateEventType,
room::{ room::{
create::RoomCreateEventContent,
join_rules::{JoinRule, RoomJoinRulesEventContent}, join_rules::{JoinRule, RoomJoinRulesEventContent},
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent}, power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
}, },
@@ -346,28 +347,44 @@ async fn user_can_publish_room(
user_id: &UserId, user_id: &UserId,
room_id: &RoomId, room_id: &RoomId,
) -> Result<bool> { ) -> Result<bool> {
match services let create_event = services
.rooms
.state_accessor
.room_state_get(room_id, &StateEventType::RoomCreate, "")
.await?;
let create_content = create_event.get_content::<RoomCreateEventContent>()?;
let room_version = &RoomVersion::new(&create_content.room_version)?;
// for >=v12, check for room creators instead
if room_version.explicitly_privilege_room_creators {
let user_is_creator = create_content
.additional_creators
.unwrap_or_default()
.iter()
.map(|id| id.as_ref())
.chain(std::iter::once(create_event.sender()))
.any(|creator| creator == user_id);
return Ok(user_is_creator);
}
// otherwise check if they can send a room history visibility state event
let power_levels_event = services
.rooms .rooms
.state_accessor .state_accessor
.room_state_get(room_id, &StateEventType::RoomPowerLevels, "") .room_state_get(room_id, &StateEventType::RoomPowerLevels, "")
.await .await;
{
| Ok(event) => serde_json::from_str(event.content().get()) match power_levels_event {
.map_err(|_| err!(Database("Invalid event content for m.room.power_levels"))) | Ok(event) => {
.map(|content: RoomPowerLevelsEventContent| { let content = event.get_content::<RoomPowerLevelsEventContent>()?;
RoomPowerLevels::from(content) let power_levels = RoomPowerLevels::from(content);
.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility) Ok(power_levels.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility))
}), },
| _ => { | Err(_) => {
match services // If there is no power levels event, fall back to checking if the user is the
.rooms // room creator
.state_accessor Ok(create_event.sender() == user_id)
.room_state_get(room_id, &StateEventType::RoomCreate, "")
.await
{
| Ok(event) => Ok(event.sender() == user_id),
| _ => Err!(Request(Forbidden("User is not allowed to publish this room"))),
}
}, },
} }
} }