Merge pull request #3520 from matrix-org/matthew/sync_deleted_devices

Announce deleted devices explicitly over federation.
This commit is contained in:
Matthew Hodgson 2018-07-23 10:16:05 +01:00 committed by GitHub
commit 354a99c968
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 22 deletions

1
changelog.d/3520.bugfix Normal file
View File

@ -0,0 +1 @@
Correctly announce deleted devices over federation

View File

@ -274,7 +274,7 @@ class Notifier(object):
logger.exception("Error notifying application services of event") logger.exception("Error notifying application services of event")
def on_new_event(self, stream_key, new_token, users=[], rooms=[]): def on_new_event(self, stream_key, new_token, users=[], rooms=[]):
""" Used to inform listeners that something has happend event wise. """ Used to inform listeners that something has happened event wise.
Will wake up all listeners for the given users and rooms. Will wake up all listeners for the given users and rooms.
""" """

View File

@ -248,17 +248,31 @@ class DeviceStore(SQLBaseStore):
def _update_remote_device_list_cache_entry_txn(self, txn, user_id, device_id, def _update_remote_device_list_cache_entry_txn(self, txn, user_id, device_id,
content, stream_id): content, stream_id):
self._simple_upsert_txn( if content.get("deleted"):
txn, self._simple_delete_txn(
table="device_lists_remote_cache", txn,
keyvalues={ table="device_lists_remote_cache",
"user_id": user_id, keyvalues={
"device_id": device_id, "user_id": user_id,
}, "device_id": device_id,
values={ },
"content": json.dumps(content), )
}
) txn.call_after(
self.device_id_exists_cache.invalidate, (user_id, device_id,)
)
else:
self._simple_upsert_txn(
txn,
table="device_lists_remote_cache",
keyvalues={
"user_id": user_id,
"device_id": device_id,
},
values={
"content": json.dumps(content),
}
)
txn.call_after(self._get_cached_user_device.invalidate, (user_id, device_id,)) txn.call_after(self._get_cached_user_device.invalidate, (user_id, device_id,))
txn.call_after(self._get_cached_devices_for_user.invalidate, (user_id,)) txn.call_after(self._get_cached_devices_for_user.invalidate, (user_id,))
@ -366,7 +380,7 @@ class DeviceStore(SQLBaseStore):
now_stream_id = max(stream_id for stream_id in itervalues(query_map)) now_stream_id = max(stream_id for stream_id in itervalues(query_map))
devices = self._get_e2e_device_keys_txn( devices = self._get_e2e_device_keys_txn(
txn, query_map.keys(), include_all_devices=True txn, query_map.keys(), include_all_devices=True, include_deleted_devices=True
) )
prev_sent_id_sql = """ prev_sent_id_sql = """
@ -393,12 +407,15 @@ class DeviceStore(SQLBaseStore):
prev_id = stream_id prev_id = stream_id
key_json = device.get("key_json", None) if device is not None:
if key_json: key_json = device.get("key_json", None)
result["keys"] = json.loads(key_json) if key_json:
device_display_name = device.get("device_display_name", None) result["keys"] = json.loads(key_json)
if device_display_name: device_display_name = device.get("device_display_name", None)
result["device_display_name"] = device_display_name if device_display_name:
result["device_display_name"] = device_display_name
else:
result["deleted"] = True
results.append(result) results.append(result)

View File

@ -64,12 +64,18 @@ class EndToEndKeyStore(SQLBaseStore):
) )
@defer.inlineCallbacks @defer.inlineCallbacks
def get_e2e_device_keys(self, query_list, include_all_devices=False): def get_e2e_device_keys(
self, query_list, include_all_devices=False,
include_deleted_devices=False,
):
"""Fetch a list of device keys. """Fetch a list of device keys.
Args: Args:
query_list(list): List of pairs of user_ids and device_ids. query_list(list): List of pairs of user_ids and device_ids.
include_all_devices (bool): whether to include entries for devices include_all_devices (bool): whether to include entries for devices
that don't have device keys that don't have device keys
include_deleted_devices (bool): whether to include null entries for
devices which no longer exist (but were in the query_list).
This option only takes effect if include_all_devices is true.
Returns: Returns:
Dict mapping from user-id to dict mapping from device_id to Dict mapping from user-id to dict mapping from device_id to
dict containing "key_json", "device_display_name". dict containing "key_json", "device_display_name".
@ -79,7 +85,7 @@ class EndToEndKeyStore(SQLBaseStore):
results = yield self.runInteraction( results = yield self.runInteraction(
"get_e2e_device_keys", self._get_e2e_device_keys_txn, "get_e2e_device_keys", self._get_e2e_device_keys_txn,
query_list, include_all_devices, query_list, include_all_devices, include_deleted_devices,
) )
for user_id, device_keys in iteritems(results): for user_id, device_keys in iteritems(results):
@ -88,10 +94,19 @@ class EndToEndKeyStore(SQLBaseStore):
defer.returnValue(results) defer.returnValue(results)
def _get_e2e_device_keys_txn(self, txn, query_list, include_all_devices): def _get_e2e_device_keys_txn(
self, txn, query_list, include_all_devices=False,
include_deleted_devices=False,
):
query_clauses = [] query_clauses = []
query_params = [] query_params = []
if include_all_devices is False:
include_deleted_devices = False
if include_deleted_devices:
deleted_devices = set(query_list)
for (user_id, device_id) in query_list: for (user_id, device_id) in query_list:
query_clause = "user_id = ?" query_clause = "user_id = ?"
query_params.append(user_id) query_params.append(user_id)
@ -119,8 +134,14 @@ class EndToEndKeyStore(SQLBaseStore):
result = {} result = {}
for row in rows: for row in rows:
if include_deleted_devices:
deleted_devices.remove((row["user_id"], row["device_id"]))
result.setdefault(row["user_id"], {})[row["device_id"]] = row result.setdefault(row["user_id"], {})[row["device_id"]] = row
if include_deleted_devices:
for user_id, device_id in deleted_devices:
result.setdefault(user_id, {})[device_id] = None
return result return result
@defer.inlineCallbacks @defer.inlineCallbacks