Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.
Merged
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/6232.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove a room from a server's public rooms list on room upgrade.
2 changes: 1 addition & 1 deletion synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ def make_membership_event(
Note that this does not append any events to any graphs.

Args:
destinations (str): Candidate homeservers which are probably
destinations (Iterable[str]): Candidate homeservers which are probably
participating in the room.
room_id (str): The room in which the event will happen.
user_id (str): The user whose membership is being evented.
Expand Down
30 changes: 29 additions & 1 deletion synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ def on_event_auth(self, event_id):
@defer.inlineCallbacks
def do_invite_join(self, target_hosts, room_id, joinee, content):
""" Attempts to join the `joinee` to the room `room_id` via the
server `target_host`.
servers contained in `target_hosts`.

This first triggers a /make_join/ request that returns a partial
event that we can fill out and sign. This is then sent to the
Expand All @@ -1115,6 +1115,15 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):

We suspend processing of any received events from this room until we
have finished processing the join.

Args:
target_hosts (Iterable[str]): List of servers to attempt to join the room with.

room_id (str): The ID of the room to join.

joinee (str): The User ID of the joining user.

content (dict): The event content to use for the join event.
"""
logger.debug("Joining %s to %s", joinee, room_id)

Expand Down Expand Up @@ -1174,6 +1183,22 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):

yield self._persist_auth_tree(origin, auth_chain, state, event)

# Check whether this room is the result of an upgrade of a room we already know
# about. If so, migrate over user information
predecessor = yield self.store.get_room_predecessor(room_id)
if not predecessor:
return
old_room_id = predecessor["room_id"]
logger.debug(
"Found predecessor for %s during remote join: %s", room_id, old_room_id
)

# We retrieve the room member handler here as to not cause a cyclic dependency
member_handler = self.hs.get_room_member_handler()
yield member_handler.transfer_room_state_on_room_upgrade(
old_room_id, room_id
)

logger.debug("Finished joining %s to %s", joinee, room_id)
finally:
room_queue = self.room_queues[room_id]
Expand Down Expand Up @@ -2442,6 +2467,8 @@ def exchange_third_party_invite(
raise e

yield self._check_signature(event, context)

# We retrieve the room member handler here as to not cause a cyclic dependency
member_handler = self.hs.get_room_member_handler()
yield member_handler.send_membership_event(None, event, context)
else:
Expand Down Expand Up @@ -2502,6 +2529,7 @@ def on_exchange_third_party_invite_request(self, room_id, event_dict):
# though the sender isn't a local user.
event.internal_metadata.send_on_behalf_of = get_domain_from_id(event.sender)

# We retrieve the room member handler here as to not cause a cyclic dependency
member_handler = self.hs.get_room_member_handler()
yield member_handler.send_membership_event(None, event, context)

Expand Down
8 changes: 7 additions & 1 deletion synapse/handlers/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def upgrade_room(self, requester, old_room_id, new_version):
old_room_id,
new_version, # args for _upgrade_room
)

return ret

@defer.inlineCallbacks
Expand Down Expand Up @@ -189,7 +190,12 @@ def _upgrade_room(self, requester, old_room_id, new_version):
requester, old_room_id, new_room_id, old_room_state
)

# and finally, shut down the PLs in the old room, and update them in the new
# Copy over user push rules, tags and migrate room directory state
yield self.room_member_handler.transfer_room_state_on_room_upgrade(
old_room_id, new_room_id
)

# 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
Expand Down
81 changes: 54 additions & 27 deletions synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,6 @@ def _local_membership_update(
prev_member_event = yield self.store.get_event(prev_member_event_id)
newly_joined = prev_member_event.membership != Membership.JOIN
if newly_joined:
# Copy over user state if we're joining an upgraded room
yield self.copy_user_state_if_room_upgrade(
room_id, requester.user.to_string()
)
yield self._user_joined_room(target, room_id)
elif event.membership == Membership.LEAVE:
if prev_member_event_id:
Expand Down Expand Up @@ -455,11 +451,6 @@ def _update_membership(
requester, remote_room_hosts, room_id, target, content
)

# Copy over user state if this is a join on an remote upgraded room
yield self.copy_user_state_if_room_upgrade(
room_id, requester.user.to_string()
)

return remote_join_response

elif effective_membership_state == Membership.LEAVE:
Expand Down Expand Up @@ -498,36 +489,72 @@ def _update_membership(
return res

@defer.inlineCallbacks
def copy_user_state_if_room_upgrade(self, new_room_id, user_id):
"""Copy user-specific information when they join a new room if that new room is the
def transfer_room_state_on_room_upgrade(self, old_room_id, room_id):
"""Upon our server becoming aware of an upgraded room, either by upgrading a room
ourselves or joining one, we can transfer over information from the previous room.

Copies user state (tags/push rules) for every local user that was in the old room, as
well as migrating the room directory state.

Args:
old_room_id (str): The ID of the old room

room_id (str): The ID of the new room

Returns:
Deferred
"""
# Find all local users that were in the old room and copy over each user's state
users = yield self.store.get_users_in_room(old_room_id)
yield self.copy_user_state_on_room_upgrade(old_room_id, room_id, users)

# Add new room to the room directory if the old room was there
# Remove old room from the room directory
old_room = yield self.store.get_room(old_room_id)
if old_room and old_room["is_public"]:
yield self.store.set_room_is_public(old_room_id, False)
yield self.store.set_room_is_public(room_id, True)

@defer.inlineCallbacks
def copy_user_state_on_room_upgrade(self, old_room_id, new_room_id, user_ids):
"""Copy user-specific information when they join a new room when that new room is the
result of a room upgrade

Args:
new_room_id (str): The ID of the room the user is joining
user_id (str): The ID of the user
old_room_id (str): The ID of upgraded room
new_room_id (str): The ID of the new room
user_ids (Iterable[str]): User IDs to copy state for

Returns:
Deferred
"""
# Check if the new room is an upgraded room
predecessor = yield self.store.get_room_predecessor(new_room_id)
if not predecessor:
return

logger.debug(
"Found predecessor for %s: %s. Copying over room tags and push " "rules",
"Copying over room tags and push rules from %s to %s for users %s",
old_room_id,
new_room_id,
predecessor,
user_ids,
)

# It is an upgraded room. Copy over old tags
yield self.copy_room_tags_and_direct_to_room(
predecessor["room_id"], new_room_id, user_id
)
# Copy over push rules
yield self.store.copy_push_rules_from_room_to_room_for_user(
predecessor["room_id"], new_room_id, user_id
)
for user_id in user_ids:
try:
# It is an upgraded room. Copy over old tags
yield self.copy_room_tags_and_direct_to_room(
old_room_id, new_room_id, user_id
)
# Copy over push rules
yield self.store.copy_push_rules_from_room_to_room_for_user(
old_room_id, new_room_id, user_id
)
except Exception:
logger.exception(
"Error copying tags and/or push rules from rooms %s to %s for user %s. "
"Skipping...",
Comment thread
anoadragon453 marked this conversation as resolved.
old_room_id,
new_room_id,
user_id,
)
continue
Comment thread
anoadragon453 marked this conversation as resolved.

@defer.inlineCallbacks
def send_membership_event(self, requester, event, context, ratelimit=True):
Expand Down