|
|
|
@ -414,34 +414,25 @@ class RoomMembershipRestServlet(ClientV1RestServlet): |
|
|
|
|
|
|
|
|
|
# target user is you unless it is an invite |
|
|
|
|
state_key = user.to_string() |
|
|
|
|
if membership_action in ["invite", "ban", "kick"]: |
|
|
|
|
try: |
|
|
|
|
|
|
|
|
|
if membership_action == "invite" and ThirdPartyInvites.has_invite_keys(content): |
|
|
|
|
yield self.handlers.room_member_handler.do_3pid_invite( |
|
|
|
|
room_id, |
|
|
|
|
user, |
|
|
|
|
content["medium"], |
|
|
|
|
content["address"], |
|
|
|
|
content["id_server"], |
|
|
|
|
content["display_name"], |
|
|
|
|
token_id, |
|
|
|
|
txn_id |
|
|
|
|
) |
|
|
|
|
defer.returnValue((200, {})) |
|
|
|
|
return |
|
|
|
|
elif membership_action in ["invite", "ban", "kick"]: |
|
|
|
|
if "user_id" in content: |
|
|
|
|
state_key = content["user_id"] |
|
|
|
|
except KeyError: |
|
|
|
|
if ( |
|
|
|
|
membership_action != "invite" or |
|
|
|
|
not ThirdPartyInvites.has_invite_keys(content) |
|
|
|
|
): |
|
|
|
|
raise SynapseError(400, "Missing user_id key.") |
|
|
|
|
|
|
|
|
|
id_server = content["id_server"] |
|
|
|
|
medium = content["medium"] |
|
|
|
|
address = content["address"] |
|
|
|
|
display_name = content["display_name"] |
|
|
|
|
state_key = yield self._lookup_3pid_user(id_server, medium, address) |
|
|
|
|
if not state_key: |
|
|
|
|
yield self._make_and_store_3pid_invite( |
|
|
|
|
id_server, |
|
|
|
|
display_name, |
|
|
|
|
medium, |
|
|
|
|
address, |
|
|
|
|
room_id, |
|
|
|
|
user, |
|
|
|
|
token_id, |
|
|
|
|
txn_id=txn_id |
|
|
|
|
) |
|
|
|
|
defer.returnValue((200, {})) |
|
|
|
|
return |
|
|
|
|
else: |
|
|
|
|
raise SynapseError(400, "Missing user_id key.") |
|
|
|
|
|
|
|
|
|
# make sure it looks like a user ID; it'll throw if it's invalid. |
|
|
|
|
UserID.from_string(state_key) |
|
|
|
@ -473,94 +464,6 @@ class RoomMembershipRestServlet(ClientV1RestServlet): |
|
|
|
|
|
|
|
|
|
defer.returnValue((200, {})) |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def _lookup_3pid_user(self, id_server, medium, address): |
|
|
|
|
"""Looks up a 3pid in the passed identity server. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
id_server (str): The server name (including port, if required) |
|
|
|
|
of the identity server to use. |
|
|
|
|
medium (str): The type of the third party identifier (e.g. "email"). |
|
|
|
|
address (str): The third party identifier (e.g. "foo@example.com"). |
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
|
(str) the matrix ID of the 3pid, or None if it is not recognized. |
|
|
|
|
""" |
|
|
|
|
try: |
|
|
|
|
data = yield self.hs.get_simple_http_client().get_json( |
|
|
|
|
"https://%s/_matrix/identity/api/v1/lookup" % (id_server,), |
|
|
|
|
{ |
|
|
|
|
"medium": medium, |
|
|
|
|
"address": address, |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if "mxid" in data: |
|
|
|
|
# TODO: Validate the response signature and such |
|
|
|
|
defer.returnValue(data["mxid"]) |
|
|
|
|
except IOError as e: |
|
|
|
|
logger.warn("Error from identity server lookup: %s" % (e,)) |
|
|
|
|
defer.returnValue(None) |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def _make_and_store_3pid_invite( |
|
|
|
|
self, |
|
|
|
|
id_server, |
|
|
|
|
display_name, |
|
|
|
|
medium, |
|
|
|
|
address, |
|
|
|
|
room_id, |
|
|
|
|
user, |
|
|
|
|
token_id, |
|
|
|
|
txn_id |
|
|
|
|
): |
|
|
|
|
token, public_key, key_validity_url = ( |
|
|
|
|
yield self._ask_id_server_for_third_party_invite( |
|
|
|
|
id_server, |
|
|
|
|
medium, |
|
|
|
|
address, |
|
|
|
|
room_id, |
|
|
|
|
user.to_string() |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
msg_handler = self.handlers.message_handler |
|
|
|
|
yield msg_handler.create_and_send_event( |
|
|
|
|
{ |
|
|
|
|
"type": EventTypes.ThirdPartyInvite, |
|
|
|
|
"content": { |
|
|
|
|
"display_name": display_name, |
|
|
|
|
"key_validity_url": key_validity_url, |
|
|
|
|
"public_key": public_key, |
|
|
|
|
}, |
|
|
|
|
"room_id": room_id, |
|
|
|
|
"sender": user.to_string(), |
|
|
|
|
"state_key": token, |
|
|
|
|
}, |
|
|
|
|
token_id=token_id, |
|
|
|
|
txn_id=txn_id, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def _ask_id_server_for_third_party_invite( |
|
|
|
|
self, id_server, medium, address, room_id, sender): |
|
|
|
|
is_url = "https://%s/_matrix/identity/api/v1/nonce-it-up" % (id_server,) |
|
|
|
|
data = yield self.hs.get_simple_http_client().post_urlencoded_get_json( |
|
|
|
|
is_url, |
|
|
|
|
{ |
|
|
|
|
"medium": medium, |
|
|
|
|
"address": address, |
|
|
|
|
"room_id": room_id, |
|
|
|
|
"sender": sender, |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
# TODO: Check for success |
|
|
|
|
token = data["token"] |
|
|
|
|
public_key = data["public_key"] |
|
|
|
|
key_validity_url = "https://%s/_matrix/identity/api/v1/pubkey/isvalid" % ( |
|
|
|
|
id_server, |
|
|
|
|
) |
|
|
|
|
defer.returnValue((token, public_key, key_validity_url)) |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def on_PUT(self, request, room_id, membership_action, txn_id): |
|
|
|
|
try: |
|
|
|
|