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

Check appservices for devices during a /user/devices query. #15539

Merged
merged 6 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15539.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Proxy `/user/devices` federation queries to application serivces for [MSC3984](https://github.com/matrix-org/matrix-spec-proposals/pull/3984).
clokep marked this conversation as resolved.
Show resolved Hide resolved
27 changes: 27 additions & 0 deletions synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,14 @@ def __init__(self, hs: "HomeServer"):
self.store = hs.get_datastores().main
self.notifier = hs.get_notifier()
self.state = hs.get_state_handler()
self._appservice_handler = hs.get_application_service_handler()
self._state_storage = hs.get_storage_controllers().state
self._auth_handler = hs.get_auth_handler()
self.server_name = hs.hostname
self._msc3852_enabled = hs.config.experimental.msc3852_enabled
self._query_appservices_for_keys = (
hs.config.experimental.msc3984_appservice_key_query
)

self.device_list_updater = DeviceListWorkerUpdater(hs)

Expand Down Expand Up @@ -328,6 +332,29 @@ async def on_federation_query_user_devices(self, user_id: str) -> JsonDict:
user_id, "self_signing"
)

# Check if the application services have any results.
if self._query_appservices_for_keys:
# Query the appservice for all devices for this user.
query: Dict[str, Optional[List[str]]] = {user_id: None}

# Query the appservices for any keys.
appservice_results = await self._appservice_handler.query_keys(query)

# Merge results, overriding anything in the database.
clokep marked this conversation as resolved.
Show resolved Hide resolved
appservice_devices = appservice_results.get("device_keys", {}).get(
user_id, {}
)

# Filter the database to only those the appservice has *not* responded with.
clokep marked this conversation as resolved.
Show resolved Hide resolved
devices = [d for d in devices if d["device_id"] not in appservice_devices]
# Add a slimmed down appservice response.
devices.extend(
{"device_id": device["device_id"], "keys": device["keys"]}
for device in appservice_devices.values()
)

# TODO Handle cross-signing keys.

return {
"user_id": user_id,
"stream_id": stream_id,
Expand Down