Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 6670bd4

Browse files
v2 3PID Invites (part of MSC2140) (#5979)
3PID invites require making a request to an identity server to check that the invited 3PID has an Matrix ID linked, and if so, what it is. These requests are being made on behalf of a user. The user will supply an identity server and an access token for that identity server. The homeserver will then forward this request with the access token (using an `Authorization` header) and, if the given identity server doesn't support v2 endpoints, will fall back to v1 (which doesn't require any access tokens). Requires: ~~#5976~~
1 parent 379d2a8 commit 6670bd4

File tree

2 files changed

+82
-23
lines changed

2 files changed

+82
-23
lines changed

changelog.d/5979.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use the v2 Identity Service API for 3PID invites.

synapse/handlers/room_member.py

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,14 @@ def do_3pid_invite(
684684
)
685685
else:
686686
yield self._make_and_store_3pid_invite(
687-
requester, id_server, medium, address, room_id, inviter, txn_id=txn_id
687+
requester,
688+
id_server,
689+
medium,
690+
address,
691+
room_id,
692+
inviter,
693+
txn_id=txn_id,
694+
id_access_token=id_access_token,
688695
)
689696

690697
@defer.inlineCallbacks
@@ -885,7 +892,15 @@ def _verify_any_signature(self, data, server_hostname):
885892

886893
@defer.inlineCallbacks
887894
def _make_and_store_3pid_invite(
888-
self, requester, id_server, medium, address, room_id, user, txn_id
895+
self,
896+
requester,
897+
id_server,
898+
medium,
899+
address,
900+
room_id,
901+
user,
902+
txn_id,
903+
id_access_token=None,
889904
):
890905
room_state = yield self.state_handler.get_current_state(room_id)
891906

@@ -934,6 +949,7 @@ def _make_and_store_3pid_invite(
934949
room_name=room_name,
935950
inviter_display_name=inviter_display_name,
936951
inviter_avatar_url=inviter_avatar_url,
952+
id_access_token=id_access_token,
937953
)
938954
)
939955

@@ -971,6 +987,7 @@ def _ask_id_server_for_third_party_invite(
971987
room_name,
972988
inviter_display_name,
973989
inviter_avatar_url,
990+
id_access_token=None,
974991
):
975992
"""
976993
Asks an identity server for a third party invite.
@@ -990,6 +1007,8 @@ def _ask_id_server_for_third_party_invite(
9901007
inviter_display_name (str): The current display name of the
9911008
inviter.
9921009
inviter_avatar_url (str): The URL of the inviter's avatar.
1010+
id_access_token (str|None): The access token to authenticate to the identity
1011+
server with
9931012
9941013
Returns:
9951014
A deferred tuple containing:
@@ -1000,11 +1019,6 @@ def _ask_id_server_for_third_party_invite(
10001019
display_name (str): A user-friendly name to represent the invited
10011020
user.
10021021
"""
1003-
is_url = "%s%s/_matrix/identity/api/v1/store-invite" % (
1004-
id_server_scheme,
1005-
id_server,
1006-
)
1007-
10081022
invite_config = {
10091023
"medium": medium,
10101024
"address": address,
@@ -1017,31 +1031,75 @@ def _ask_id_server_for_third_party_invite(
10171031
"sender_display_name": inviter_display_name,
10181032
"sender_avatar_url": inviter_avatar_url,
10191033
}
1020-
try:
1021-
data = yield self.simple_http_client.post_json_get_json(
1022-
is_url, invite_config
1023-
)
1024-
except HttpResponseException as e:
1025-
# Some identity servers may only support application/x-www-form-urlencoded
1026-
# types. This is especially true with old instances of Sydent, see
1027-
# https://github.com/matrix-org/sydent/pull/170
1028-
logger.info(
1029-
"Failed to POST %s with JSON, falling back to urlencoded form: %s",
1030-
is_url,
1031-
e,
1034+
1035+
# Add the identity service access token to the JSON body and use the v2
1036+
# Identity Service endpoints if id_access_token is present
1037+
data = None
1038+
base_url = "%s%s/_matrix/identity" % (id_server_scheme, id_server)
1039+
1040+
if id_access_token:
1041+
key_validity_url = "%s%s/_matrix/identity/v2/pubkey/isvalid" % (
1042+
id_server_scheme,
1043+
id_server,
10321044
)
1033-
data = yield self.simple_http_client.post_urlencoded_get_json(
1034-
is_url, invite_config
1045+
1046+
# Attempt a v2 lookup
1047+
url = base_url + "/v2/store-invite"
1048+
try:
1049+
data = yield self.simple_http_client.post_json_get_json(
1050+
url,
1051+
invite_config,
1052+
{"Authorization": create_id_access_token_header(id_access_token)},
1053+
)
1054+
except HttpResponseException as e:
1055+
if e.code != 404:
1056+
logger.info("Failed to POST %s with JSON: %s", url, e)
1057+
raise e
1058+
1059+
if data is None:
1060+
key_validity_url = "%s%s/_matrix/identity/api/v1/pubkey/isvalid" % (
1061+
id_server_scheme,
1062+
id_server,
10351063
)
1064+
url = base_url + "/api/v1/store-invite"
1065+
1066+
try:
1067+
data = yield self.simple_http_client.post_json_get_json(
1068+
url, invite_config
1069+
)
1070+
except HttpResponseException as e:
1071+
logger.warning(
1072+
"Error trying to call /store-invite on %s%s: %s",
1073+
id_server_scheme,
1074+
id_server,
1075+
e,
1076+
)
1077+
1078+
if data is None:
1079+
# Some identity servers may only support application/x-www-form-urlencoded
1080+
# types. This is especially true with old instances of Sydent, see
1081+
# https://github.com/matrix-org/sydent/pull/170
1082+
try:
1083+
data = yield self.simple_http_client.post_urlencoded_get_json(
1084+
url, invite_config
1085+
)
1086+
except HttpResponseException as e:
1087+
logger.warning(
1088+
"Error calling /store-invite on %s%s with fallback "
1089+
"encoding: %s",
1090+
id_server_scheme,
1091+
id_server,
1092+
e,
1093+
)
1094+
raise e
10361095

10371096
# TODO: Check for success
10381097
token = data["token"]
10391098
public_keys = data.get("public_keys", [])
10401099
if "public_key" in data:
10411100
fallback_public_key = {
10421101
"public_key": data["public_key"],
1043-
"key_validity_url": "%s%s/_matrix/identity/api/v1/pubkey/isvalid"
1044-
% (id_server_scheme, id_server),
1102+
"key_validity_url": key_validity_url,
10451103
}
10461104
else:
10471105
fallback_public_key = public_keys[0]

0 commit comments

Comments
 (0)