summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrendan Abolivier <babolivier@matrix.org>2019-10-02 11:16:38 +0100
committerBrendan Abolivier <babolivier@matrix.org>2019-10-02 11:19:43 +0100
commit5705ecaec6b7a85c152691c79a4fa3526792a3eb (patch)
tree6ba35f061796f3bfc948f6b5684ae1d5f5e45f59
parentMerge branch 'erikj/fixup_devices_last_seen_query' of github.com:matrix-org/s... (diff)
downloadsynapse-5705ecaec6b7a85c152691c79a4fa3526792a3eb.tar.xz
Don't 500 code when trying to exchange a revoked 3PID invite
While this is not documented in the spec (but should be), Riot (and other clients) revoke 3PID invites by sending a m.room.third_party_invite event with an empty ({}) content to the room's state.
When the invited 3PID gets associated with a MXID, the identity server (which doesn't know about revocations) sends down to the MXID's homeserver all of the undelivered invites it has for this 3PID. The homeserver then tries to talk to the inviting homeserver in order to exchange these invite for m.room.member events.
When one of the invite is revoked, the inviting homeserver responds with a 500 error because it tries to extract a 'display_name' property from the content, which is empty. This might cause the invited server to consider that the server is down and not try to exchange other, valid invites (or at least delay it).

This fix handles the case of revoked invites by avoiding trying to fetch a 'display_name' from the original invite's content, and letting the m.room.member event fail the auth rules (because, since the original invite's content is empty, it doesn't have public keys), which results in sending a 403 with the correct error message to the invited server.
-rw-r--r--synapse/handlers/federation.py15
1 files changed, 13 insertions, 2 deletions
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index f72b81d419..a3d7739ead 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -2599,8 +2599,19 @@ class FederationHandler(BaseHandler):
                 original_invite_id, allow_none=True
             )
         if original_invite:
-            display_name = original_invite.content["display_name"]
-            event_dict["content"]["third_party_invite"]["display_name"] = display_name
+            # If the m.room.third_party_invite event's content is empty, it means the
+            # invite has been revoked.
+            if original_invite.content:
+                display_name = original_invite.content["display_name"]
+                event_dict["content"]["third_party_invite"]["display_name"] = display_name
+            else:
+                # Don't discard or raise an error here because that's not the right place
+                # to do auth checks. The auth check will fail on this invite because we
+                # won't be able to fetch public keys from the m.room.third_party_invite
+                # event's content (because it's empty).
+                logger.info(
+                    "Found invite event for third_party_invite but it has been revoked"
+                )
         else:
             logger.info(
                 "Could not find invite event for third_party_invite: %r", event_dict