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

Commit

Permalink
Fix and de-brittle remote result dict processing
Browse files Browse the repository at this point in the history
  • Loading branch information
anoadragon453 committed Apr 20, 2020
1 parent c265bc7 commit 39ed9f6
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions synapse/handlers/e2e_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -985,35 +985,49 @@ def _get_e2e_cross_signing_verify_key(self, user_id, key_type, from_user_id=None
Raises:
NotFoundError: if the key is not found
"""
user = UserID.from_string(user_id)
key = yield self.store.get_e2e_cross_signing_key(
user_id, key_type, from_user_id
)
if key is None:

if key is None and self.is_mine(user):
# Attempt to fetch the missing key from the remote user's server
user = UserID.from_string(user_id)
try:
remote_result = yield self.federation.query_client_keys(
user.domain, {"device_keys": {user_id: []}}, timeout=10 * 1000
)

# Save these keys to the database for subsequent queries
for key_type, remote_user_id in remote_result.items():
if remote_user_id != user_id:
continue
key_contents = remote_result[key_type][remote_user_id]
key_type = key_type[:-5] # Remove the "_keys" from the key type

yield self.store.set_e2e_cross_signing_key(
user_id, key_type, key_contents
)

# The key_type variable passed to this function is in the form
# "self_signing","master" etc. Whereas the results returned from
# the remote server use "self_signing_keys", "master_keys" etc.
# Translate that here.
remote_key_type = key_type + "_keys"

key = remote_result.get(remote_key_type, {}).get(user_id)
# Process the result
for remote_key_type, remote_user_dict in remote_result.items():
# The key_type variable passed to this function is in the form
# "self_signing","master" etc. whereas the results returned from
# the remote server use "self_signing_keys", "master_keys" etc.
# Remove the "_keys" from the key type
if remote_key_type.endswith("_keys"):
remote_key_type = remote_key_type[:-5]

# remote_user_dict is a dictionary in the form of
# {
# "user_id": {
# "master_keys": ...
# },
# ...
# }

# Only extract the keys that pertain to the requested user
key_content_list = remote_user_dict.get(user_id, {}).values()

for key_content in key_content_list:
# If the key_type here matches the key we're requesting,
# then this is the key we want to return
if remote_key_type == key_type:
key = key_content

# At the same time, save the key to the database for subsequent
# queries
yield self.store.set_e2e_cross_signing_key(
user_id, remote_key_type, key_content
)
except (
HttpResponseException,
NotRetryingDestination,
Expand Down

0 comments on commit 39ed9f6

Please sign in to comment.