Depublish a room from the public rooms list when it is upgraded (#6232)
parent
53d7680e32
commit
ace947e8da
|
@ -0,0 +1 @@
|
||||||
|
Remove a room from a server's public rooms list on room upgrade.
|
|
@ -555,7 +555,7 @@ class FederationClient(FederationBase):
|
||||||
Note that this does not append any events to any graphs.
|
Note that this does not append any events to any graphs.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
destinations (str): Candidate homeservers which are probably
|
destinations (Iterable[str]): Candidate homeservers which are probably
|
||||||
participating in the room.
|
participating in the room.
|
||||||
room_id (str): The room in which the event will happen.
|
room_id (str): The room in which the event will happen.
|
||||||
user_id (str): The user whose membership is being evented.
|
user_id (str): The user whose membership is being evented.
|
||||||
|
|
|
@ -1106,7 +1106,7 @@ class FederationHandler(BaseHandler):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def do_invite_join(self, target_hosts, room_id, joinee, content):
|
def do_invite_join(self, target_hosts, room_id, joinee, content):
|
||||||
""" Attempts to join the `joinee` to the room `room_id` via the
|
""" 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
|
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
|
event that we can fill out and sign. This is then sent to the
|
||||||
|
@ -1115,6 +1115,15 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
We suspend processing of any received events from this room until we
|
We suspend processing of any received events from this room until we
|
||||||
have finished processing the join.
|
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)
|
logger.debug("Joining %s to %s", joinee, room_id)
|
||||||
|
|
||||||
|
@ -1174,6 +1183,22 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
yield self._persist_auth_tree(origin, auth_chain, state, event)
|
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)
|
logger.debug("Finished joining %s to %s", joinee, room_id)
|
||||||
finally:
|
finally:
|
||||||
room_queue = self.room_queues[room_id]
|
room_queue = self.room_queues[room_id]
|
||||||
|
@ -2442,6 +2467,8 @@ class FederationHandler(BaseHandler):
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
yield self._check_signature(event, context)
|
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()
|
member_handler = self.hs.get_room_member_handler()
|
||||||
yield member_handler.send_membership_event(None, event, context)
|
yield member_handler.send_membership_event(None, event, context)
|
||||||
else:
|
else:
|
||||||
|
@ -2502,6 +2529,7 @@ class FederationHandler(BaseHandler):
|
||||||
# though the sender isn't a local user.
|
# though the sender isn't a local user.
|
||||||
event.internal_metadata.send_on_behalf_of = get_domain_from_id(event.sender)
|
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()
|
member_handler = self.hs.get_room_member_handler()
|
||||||
yield member_handler.send_membership_event(None, event, context)
|
yield member_handler.send_membership_event(None, event, context)
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ class RoomCreationHandler(BaseHandler):
|
||||||
old_room_id,
|
old_room_id,
|
||||||
new_version, # args for _upgrade_room
|
new_version, # args for _upgrade_room
|
||||||
)
|
)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
@ -189,7 +190,12 @@ class RoomCreationHandler(BaseHandler):
|
||||||
requester, old_room_id, new_room_id, old_room_state
|
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.
|
# room.
|
||||||
yield self._update_upgraded_room_pls(
|
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
|
||||||
|
|
|
@ -203,10 +203,6 @@ class RoomMemberHandler(object):
|
||||||
prev_member_event = yield self.store.get_event(prev_member_event_id)
|
prev_member_event = yield self.store.get_event(prev_member_event_id)
|
||||||
newly_joined = prev_member_event.membership != Membership.JOIN
|
newly_joined = prev_member_event.membership != Membership.JOIN
|
||||||
if newly_joined:
|
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)
|
yield self._user_joined_room(target, room_id)
|
||||||
elif event.membership == Membership.LEAVE:
|
elif event.membership == Membership.LEAVE:
|
||||||
if prev_member_event_id:
|
if prev_member_event_id:
|
||||||
|
@ -455,11 +451,6 @@ class RoomMemberHandler(object):
|
||||||
requester, remote_room_hosts, room_id, target, content
|
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
|
return remote_join_response
|
||||||
|
|
||||||
elif effective_membership_state == Membership.LEAVE:
|
elif effective_membership_state == Membership.LEAVE:
|
||||||
|
@ -498,36 +489,72 @@ class RoomMemberHandler(object):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def copy_user_state_if_room_upgrade(self, new_room_id, user_id):
|
def transfer_room_state_on_room_upgrade(self, old_room_id, room_id):
|
||||||
"""Copy user-specific information when they join a new room if that new room is the
|
"""Upon our server becoming aware of an upgraded room, either by upgrading a room
|
||||||
result of a room upgrade
|
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:
|
Args:
|
||||||
new_room_id (str): The ID of the room the user is joining
|
old_room_id (str): The ID of the old room
|
||||||
user_id (str): The ID of the user
|
|
||||||
|
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:
|
||||||
|
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:
|
Returns:
|
||||||
Deferred
|
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(
|
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,
|
new_room_id,
|
||||||
predecessor,
|
user_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
# It is an upgraded room. Copy over old tags
|
for user_id in user_ids:
|
||||||
yield self.copy_room_tags_and_direct_to_room(
|
try:
|
||||||
predecessor["room_id"], new_room_id, user_id
|
# It is an upgraded room. Copy over old tags
|
||||||
)
|
yield self.copy_room_tags_and_direct_to_room(
|
||||||
# Copy over push rules
|
old_room_id, new_room_id, user_id
|
||||||
yield self.store.copy_push_rules_from_room_to_room_for_user(
|
)
|
||||||
predecessor["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...",
|
||||||
|
old_room_id,
|
||||||
|
new_room_id,
|
||||||
|
user_id,
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def send_membership_event(self, requester, event, context, ratelimit=True):
|
def send_membership_event(self, requester, event, context, ratelimit=True):
|
||||||
|
|
Loading…
Reference in New Issue