Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/18818.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug where room creators would be set to the default power level when downgrading v12 rooms.
4 changes: 2 additions & 2 deletions synapse/events/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,8 +763,8 @@ def copy_and_fixup_power_levels_contents(
integer, e.g. `"`100"` instead of 100. Such strings are converted to integers
in the returned dictionary (hence "fixup" in the function name).

Note that future room versions will outlaw such stringy power levels (see
https://github.com/matrix-org/matrix-spec/issues/853).
Note that room versions 10+ outlaws such stringy power levels (see
https://github.com/matrix-org/matrix-spec-proposals/pull/3667).

Raises:
TypeError if the input does not look like a valid power levels event content
Expand Down
59 changes: 25 additions & 34 deletions synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,34 +419,27 @@ async def _upgrade_room(
old_room_id, new_room_id
)

# finally, shut down the PLs in the old room, and update them in the new
# room.
await self._update_upgraded_room_pls(
# finally, shut down the PLs in the old room
await self._shutdown_power_levels_in_upgraded_room(
requester,
old_room_id,
new_room_id,
old_room_state,
additional_creators,
)

return new_room_id

async def _update_upgraded_room_pls(
async def _shutdown_power_levels_in_upgraded_room(
self,
requester: Requester,
old_room_id: str,
new_room_id: str,
old_room_state: StateMap[str],
additional_creators: Optional[List[str]],
) -> None:
"""Send updated power levels in both rooms after an upgrade
"""Send updated power levels in the old room after it has been upgraded

Args:
requester: the user requesting the upgrade
old_room_id: the id of the room to be replaced
new_room_id: the id of the replacement room
old_room_state: the state map for the old room
additional_creators: Additional creators in the new room.
Raises:
ShadowBanError if the requester is shadow-banned.
"""
Expand Down Expand Up @@ -502,28 +495,6 @@ async def _update_upgraded_room_pls(
except AuthError as e:
logger.warning("Unable to update PLs in old room: %s", e)

new_room_version = await self.store.get_room_version(new_room_id)
if new_room_version.msc4289_creator_power_enabled:
self._remove_creators_from_pl_users_map(
old_room_pl_state.content.get("users", {}),
requester.user.to_string(),
additional_creators,
)

await self.event_creation_handler.create_and_send_nonmember_event(
requester,
{
"type": EventTypes.PowerLevels,
"state_key": "",
"room_id": new_room_id,
"sender": requester.user.to_string(),
"content": copy_and_fixup_power_levels_contents(
old_room_pl_state.content
),
},
ratelimit=False,
)

def _calculate_upgraded_room_creation_content(
self,
old_room_create_event: EventBase,
Expand Down Expand Up @@ -685,8 +656,28 @@ async def clone_existing_room(
if current_power_level_int < needed_power_level:
user_power_levels[user_id] = needed_power_level

# If downgrading from a room that supports MSC4289 to one that doesn't...
if (
old_room_create_event.room_version.msc4289_creator_power_enabled
and not new_room_version.msc4289_creator_power_enabled
):
# Additionally raise the power levels of all `additional_creators` in the old
# room to the `needed_power_level` in the new room.
old_room_additional_creators = old_room_create_event.content.get(
"additional_creators", []
)
for user_id in old_room_additional_creators:
old_power_level = user_power_levels.get(user_id, users_default)
try:
old_power_level = int(old_power_level) # type: ignore[arg-type]
except (TypeError, ValueError):
old_power_level = 0

# Raise the requester's power level in the new room if necessary
if old_power_level < needed_power_level:
user_power_levels[user_id] = needed_power_level

if new_room_version.msc4289_creator_power_enabled:
# the creator(s) cannot be in the users map
self._remove_creators_from_pl_users_map(
user_power_levels,
user_id,
Expand Down
Loading