Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Transfer power level state events on room upgrade #6237

Merged
merged 12 commits into from
Dec 2, 2019
Merged
1 change: 1 addition & 0 deletions changelog.d/6237.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Transfer non-standard power levels on room upgrade.
36 changes: 31 additions & 5 deletions synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,21 +198,21 @@ def _upgrade_room(self, requester, old_room_id, new_version):
# finally, shut down the PLs in the old room, and update them in the new
# room.
yield self._update_upgraded_room_pls(
requester, old_room_id, new_room_id, old_room_state
requester, old_room_id, new_room_id, old_room_state,
)

return new_room_id

@defer.inlineCallbacks
def _update_upgraded_room_pls(
self, requester, old_room_id, new_room_id, old_room_state
self, requester, old_room_id, new_room_id, old_room_state,
):
"""Send updated power levels in both rooms after an upgrade

Args:
requester (synapse.types.Requester): the user requesting the upgrade
old_room_id (unicode): the id of the room to be replaced
new_room_id (unicode): the id of the replacement room
old_room_id (str): the id of the room to be replaced
new_room_id (str): the id of the replacement room
old_room_state (dict[tuple[str, str], str]): the state map for the old room

Returns:
Expand Down Expand Up @@ -298,7 +298,7 @@ def clone_existing_room(
tombstone_event_id (unicode|str): the ID of the tombstone event in the old
room.
Returns:
Deferred[None]
Deferred
"""
user_id = requester.user.to_string()

Expand Down Expand Up @@ -333,6 +333,7 @@ def clone_existing_room(
(EventTypes.Encryption, ""),
(EventTypes.ServerACL, ""),
(EventTypes.RelatedGroups, ""),
(EventTypes.PowerLevels, ""),
)

old_room_state_ids = yield self.store.get_filtered_current_state_ids(
Expand All @@ -346,6 +347,31 @@ def clone_existing_room(
if old_event:
initial_state[k] = old_event.content

# Resolve the minimum power level required to send any state event
# We will give the upgrading user this power level temporarily (if necessary) such that
# they are able to copy all of the state events over, then revert them back to their
# original power level afterwards
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved

# Copy over user power levels now as this will not be possible with >100PL users once
# the room has been created

power_levels = initial_state[(EventTypes.PowerLevels, "")]

# Calculate the minimum power level needed to clone the room
event_power_levels = power_levels.get("events", {})
state_default = power_levels.get("state_default", 0)
ban = power_levels.get("ban")
needed_power_level = max(state_default, ban, max(event_power_levels.values()))

# Raise the requester's power level in the new room if necessary
current_power_level = power_levels["users"][requester.user.to_string()]
if current_power_level < needed_power_level:
# Assign this power level to the requester
power_levels["users"][requester.user.to_string()] = needed_power_level

# Set the power levels to the modified state
initial_state[(EventTypes.PowerLevels, "")] = power_levels

yield self._send_events_for_new_room(
requester,
new_room_id,
Expand Down