From 8a1d3b86af5a6b23bd45ed137a4eb2b53c274297 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 1 Mar 2016 17:27:22 +0000 Subject: [PATCH 1/7] Handle rejections of invites from local users locally Slightly hacky fix to SYN-642, which avoids the federation codepath when trying to reject invites from local users. --- synapse/handlers/_base.py | 16 +++++++++++++--- synapse/handlers/room.py | 23 ++++++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py index bdade98bf7..51bd1ee4de 100644 --- a/synapse/handlers/_base.py +++ b/synapse/handlers/_base.py @@ -199,8 +199,7 @@ class BaseHandler(object): # events in the room, because we don't know enough about the graph # fragment we received to treat it like a graph, so the above returned # no relevant events. It may have returned some events (if we have - # joined and left the room), but not useful ones, like the invite. So we - # forcibly set our context to the invite we received over federation. + # joined and left the room), but not useful ones, like the invite. if ( not self.is_host_in_room(context.current_state) and builder.type == EventTypes.Member @@ -208,7 +207,18 @@ class BaseHandler(object): prev_member_event = yield self.store.get_room_member( builder.sender, builder.room_id ) - if prev_member_event: + + # if we have the prev_member_event in context, we didn't receive + # the invite over federation. (More likely is that the inviting + # user, and all other local users, have left, making + # is_host_in_room return false). + # + context_events = (e.event_id for e in context.current_state.values()) + + if prev_member_event and not prev_member_event.event_id in context_events: + # The prev_member_event is missing from context, so it must + # have arrived over federation and is an outlier. We forcibly + # set our context to the invite we received over federation builder.prev_events = ( prev_member_event.event_id, prev_member_event.prev_events diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index d2de23a6cc..714bff1750 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -521,8 +521,24 @@ class RoomMemberHandler(BaseHandler): action = "remote_join" elif event.membership == Membership.LEAVE: is_host_in_room = self.is_host_in_room(context.current_state) + if not is_host_in_room: - action = "remote_reject" + # perhaps we've been invited + inviter = self.get_inviter(target_user.to_string(), context.current_state) + if not inviter: + raise SynapseError(404, "Not a known room") + + if inviter.domain == self.server_name: + # the inviter was on our server, but has now left. Carry on + # with the normal rejection codepath. + # + # This is a bit of a hack, because the room might still be + # active on other servers. + pass + else: + # send the rejection to the inviter's HS. + remote_room_hosts = [inviter.domain] + action = "remote_reject" federation_handler = self.hs.get_handlers().federation_handler @@ -541,11 +557,8 @@ class RoomMemberHandler(BaseHandler): event.content, ) elif action == "remote_reject": - inviter = self.get_inviter(target_user.to_string(), context.current_state) - if not inviter: - raise SynapseError(404, "No known servers") yield federation_handler.do_remotely_reject_invite( - [inviter.domain], + remote_room_hosts, room_id, event.user_id ) From 05ea111c47efaec7f24cbe4c9bfae972d4b1f87f Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 1 Mar 2016 17:45:24 +0000 Subject: [PATCH 2/7] Fix pyflakes warning --- synapse/handlers/_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py index 51bd1ee4de..c1f40a4ec0 100644 --- a/synapse/handlers/_base.py +++ b/synapse/handlers/_base.py @@ -215,7 +215,7 @@ class BaseHandler(object): # context_events = (e.event_id for e in context.current_state.values()) - if prev_member_event and not prev_member_event.event_id in context_events: + if prev_member_event and prev_member_event.event_id not in context_events: # The prev_member_event is missing from context, so it must # have arrived over federation and is an outlier. We forcibly # set our context to the invite we received over federation From 9ff940a0ef22304732f31fb3d2256afc2aca6bc4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 2 Mar 2016 15:40:30 +0000 Subject: [PATCH 3/7] Address review comments --- synapse/handlers/_base.py | 20 ++++++++++++++------ synapse/handlers/room.py | 5 +++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py index c1f40a4ec0..363b10e3b7 100644 --- a/synapse/handlers/_base.py +++ b/synapse/handlers/_base.py @@ -208,14 +208,22 @@ class BaseHandler(object): builder.sender, builder.room_id ) - # if we have the prev_member_event in context, we didn't receive - # the invite over federation. (More likely is that the inviting - # user, and all other local users, have left, making - # is_host_in_room return false). + # The prev_member_event may already be in context.current_state, + # despite us not being present in the room; in particular, if + # inviting user, and all other local users, have already left. # - context_events = (e.event_id for e in context.current_state.values()) + # In that case, we have all the information we need, and we don't + # want to drop "context" - not least because we may need to handle + # the invite locally, which will require us to have the whole + # context (not just prev_member_event) to auth it. + # + context_event_ids = ( + e.event_id for e in context.current_state.values() + ) - if prev_member_event and prev_member_event.event_id not in context_events: + if (prev_member_event and + prev_member_event.event_id not in context_event_ids + ): # The prev_member_event is missing from context, so it must # have arrived over federation and is an outlier. We forcibly # set our context to the invite we received over federation diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index 714bff1750..de72398588 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -528,7 +528,7 @@ class RoomMemberHandler(BaseHandler): if not inviter: raise SynapseError(404, "Not a known room") - if inviter.domain == self.server_name: + if self.hs.is_mine(inviter): # the inviter was on our server, but has now left. Carry on # with the normal rejection codepath. # @@ -537,7 +537,8 @@ class RoomMemberHandler(BaseHandler): pass else: # send the rejection to the inviter's HS. - remote_room_hosts = [inviter.domain] + remote_room_hosts = remote_room_hosts or [] + remote_room_hosts.append(inviter.domain) action = "remote_reject" federation_handler = self.hs.get_handlers().federation_handler From 863d3f26b326b1129cbf7edfb8c5344f3e25a849 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 2 Mar 2016 15:52:50 +0000 Subject: [PATCH 4/7] fix pyflakes quibble --- synapse/handlers/_base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py index 363b10e3b7..a6f890e0b6 100644 --- a/synapse/handlers/_base.py +++ b/synapse/handlers/_base.py @@ -221,7 +221,8 @@ class BaseHandler(object): e.event_id for e in context.current_state.values() ) - if (prev_member_event and + if ( + prev_member_event and prev_member_event.event_id not in context_event_ids ): # The prev_member_event is missing from context, so it must From fc1f932cc04ed6675fb839b58d81d5ac6c23b4c5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 2 Mar 2016 16:44:14 +0000 Subject: [PATCH 5/7] Move arg default to the start of the function Also don't overwrite the list that gets passed in. --- synapse/handlers/room.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index de72398588..9ef3219e39 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -493,6 +493,8 @@ class RoomMemberHandler(BaseHandler): Raises: SynapseError if there was a problem changing the membership. """ + remote_room_hosts = remote_room_hosts or [] + target_user = UserID.from_string(event.state_key) room_id = event.room_id @@ -537,8 +539,7 @@ class RoomMemberHandler(BaseHandler): pass else: # send the rejection to the inviter's HS. - remote_room_hosts = remote_room_hosts or [] - remote_room_hosts.append(inviter.domain) + remote_room_hosts = remote_room_hosts + [inviter.doman] action = "remote_reject" federation_handler = self.hs.get_handlers().federation_handler From 74cd80e53026d9f603e9e4f9a41cef54de239e16 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Thu, 3 Mar 2016 10:28:58 +0000 Subject: [PATCH 6/7] Fix typo --- synapse/handlers/room.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index 9ef3219e39..ad7c83f477 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -539,7 +539,7 @@ class RoomMemberHandler(BaseHandler): pass else: # send the rejection to the inviter's HS. - remote_room_hosts = remote_room_hosts + [inviter.doman] + remote_room_hosts = remote_room_hosts + [inviter.domain] action = "remote_reject" federation_handler = self.hs.get_handlers().federation_handler