Compare commits

...
Sign in to create a new pull request.

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
changelog.d/1275.bugfix Normal file
View file

@ -0,0 +1 @@
Fixed room creators (in v12 rooms) being unable to publish rooms to the room directory. Contributed by @nex.

View file

@ -1,7 +1,7 @@
use axum::extract::State;
use axum_client_ip::InsecureClientIp;
use conduwuit::{
Err, Event, Result, err, info,
Err, Event, Result, RoomVersion, err, info,
utils::{
TryFutureExtExt,
math::Expected,
@ -30,6 +30,7 @@ use ruma::{
events::{
StateEventType,
room::{
create::RoomCreateEventContent,
join_rules::{JoinRule, RoomJoinRulesEventContent},
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
},
@ -346,28 +347,44 @@ async fn user_can_publish_room(
user_id: &UserId,
room_id: &RoomId,
) -> 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
.state_accessor
.room_state_get(room_id, &StateEventType::RoomPowerLevels, "")
.await
{
| Ok(event) => serde_json::from_str(event.content().get())
.map_err(|_| err!(Database("Invalid event content for m.room.power_levels")))
.map(|content: RoomPowerLevelsEventContent| {
RoomPowerLevels::from(content)
.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility)
}),
| _ => {
match services
.rooms
.state_accessor
.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"))),
}
.await;
match power_levels_event {
| Ok(event) => {
let content = event.get_content::<RoomPowerLevelsEventContent>()?;
let power_levels = RoomPowerLevels::from(content);
Ok(power_levels.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility))
},
| Err(_) => {
// If there is no power levels event, fall back to checking if the user is the
// room creator
Ok(create_event.sender() == user_id)
},
}
}