forked from MirrorHub/synapse
Merge pull request #4099 from matrix-org/rav/upgrade_odd_pls
Better handling of odd PLs during room upgrades
This commit is contained in:
commit
56ca578f77
2 changed files with 80 additions and 42 deletions
1
changelog.d/4099.feature
Normal file
1
changelog.d/4099.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Support for replacing rooms with new ones
|
|
@ -136,53 +136,91 @@ class RoomCreationHandler(BaseHandler):
|
||||||
requester, tombstone_event, tombstone_context,
|
requester, tombstone_event, tombstone_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# and finally, shut down the PLs in the old room, and update them in the new
|
||||||
|
# room.
|
||||||
old_room_state = yield tombstone_context.get_current_state_ids(self.store)
|
old_room_state = yield tombstone_context.get_current_state_ids(self.store)
|
||||||
old_room_pl_event_id = old_room_state.get((EventTypes.PowerLevels, ""))
|
|
||||||
|
|
||||||
if old_room_pl_event_id is None:
|
yield self._update_upgraded_room_pls(
|
||||||
logger.warning(
|
requester, old_room_id, new_room_id, old_room_state,
|
||||||
"Not supported: upgrading a room with no PL event. Not setting PLs "
|
)
|
||||||
"in old room.",
|
|
||||||
|
defer.returnValue(new_room_id)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def _update_upgraded_room_pls(
|
||||||
|
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_state (dict[tuple[str, str], str]): the state map for the old room
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deferred
|
||||||
|
"""
|
||||||
|
old_room_pl_event_id = old_room_state.get((EventTypes.PowerLevels, ""))
|
||||||
|
|
||||||
|
if old_room_pl_event_id is None:
|
||||||
|
logger.warning(
|
||||||
|
"Not supported: upgrading a room with no PL event. Not setting PLs "
|
||||||
|
"in old room.",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
old_room_pl_state = yield self.store.get_event(old_room_pl_event_id)
|
||||||
|
|
||||||
|
# we try to stop regular users from speaking by setting the PL required
|
||||||
|
# to send regular events and invites to 'Moderator' level. That's normally
|
||||||
|
# 50, but if the default PL in a room is 50 or more, then we set the
|
||||||
|
# required PL above that.
|
||||||
|
|
||||||
|
pl_content = dict(old_room_pl_state.content)
|
||||||
|
users_default = int(pl_content.get("users_default", 0))
|
||||||
|
restricted_level = max(users_default + 1, 50)
|
||||||
|
|
||||||
|
updated = False
|
||||||
|
for v in ("invite", "events_default"):
|
||||||
|
current = int(pl_content.get(v, 0))
|
||||||
|
if current < restricted_level:
|
||||||
|
logger.info(
|
||||||
|
"Setting level for %s in %s to %i (was %i)",
|
||||||
|
v, old_room_id, restricted_level, current,
|
||||||
)
|
)
|
||||||
|
pl_content[v] = restricted_level
|
||||||
|
updated = True
|
||||||
else:
|
else:
|
||||||
# we try to stop regular users from speaking by setting the PL required
|
logger.info(
|
||||||
# to send regular events and invites to 'Moderator' level. That's normally
|
"Not setting level for %s (already %i)",
|
||||||
# 50, but if the default PL in a room is 50 or more, then we set the
|
v, current,
|
||||||
# required PL above that.
|
)
|
||||||
|
|
||||||
old_room_pl_state = yield self.store.get_event(old_room_pl_event_id)
|
if updated:
|
||||||
pl_content = dict(old_room_pl_state.content)
|
try:
|
||||||
users_default = int(pl_content.get("users_default", 0))
|
yield self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
restricted_level = max(users_default + 1, 50)
|
requester, {
|
||||||
|
"type": EventTypes.PowerLevels,
|
||||||
|
"state_key": '',
|
||||||
|
"room_id": old_room_id,
|
||||||
|
"sender": requester.user.to_string(),
|
||||||
|
"content": pl_content,
|
||||||
|
}, ratelimit=False,
|
||||||
|
)
|
||||||
|
except AuthError as e:
|
||||||
|
logger.warning("Unable to update PLs in old room: %s", e)
|
||||||
|
|
||||||
updated = False
|
logger.info("Setting correct PLs in new room")
|
||||||
for v in ("invite", "events_default"):
|
yield self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
current = int(pl_content.get(v, 0))
|
requester, {
|
||||||
if current < restricted_level:
|
"type": EventTypes.PowerLevels,
|
||||||
logger.debug(
|
"state_key": '',
|
||||||
"Setting level for %s in %s to %i (was %i)",
|
"room_id": new_room_id,
|
||||||
v, old_room_id, restricted_level, current,
|
"sender": requester.user.to_string(),
|
||||||
)
|
"content": old_room_pl_state.content,
|
||||||
pl_content[v] = restricted_level
|
}, ratelimit=False,
|
||||||
updated = True
|
)
|
||||||
else:
|
|
||||||
logger.debug(
|
|
||||||
"Not setting level for %s (already %i)",
|
|
||||||
v, current,
|
|
||||||
)
|
|
||||||
|
|
||||||
if updated:
|
|
||||||
yield self.event_creation_handler.create_and_send_nonmember_event(
|
|
||||||
requester, {
|
|
||||||
"type": EventTypes.PowerLevels,
|
|
||||||
"state_key": '',
|
|
||||||
"room_id": old_room_id,
|
|
||||||
"sender": user_id,
|
|
||||||
"content": pl_content,
|
|
||||||
}, ratelimit=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
defer.returnValue(new_room_id)
|
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def clone_exiting_room(
|
def clone_exiting_room(
|
||||||
|
@ -223,7 +261,6 @@ class RoomCreationHandler(BaseHandler):
|
||||||
initial_state = dict()
|
initial_state = dict()
|
||||||
|
|
||||||
types_to_copy = (
|
types_to_copy = (
|
||||||
(EventTypes.PowerLevels, ""),
|
|
||||||
(EventTypes.JoinRules, ""),
|
(EventTypes.JoinRules, ""),
|
||||||
(EventTypes.Name, ""),
|
(EventTypes.Name, ""),
|
||||||
(EventTypes.Topic, ""),
|
(EventTypes.Topic, ""),
|
||||||
|
|
Loading…
Reference in a new issue