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

Delete server-side backup keys when deactivating an account. #15181

Merged
merged 16 commits into from
Apr 4, 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/15181.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Delete server-side backup keys when deactivating an account.
3 changes: 3 additions & 0 deletions synapse/handlers/deactivate_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ async def deactivate_account(
# Remove account data (including ignored users and push rules).
await self.store.purge_account_data_for_user(user_id)

# Delete any server-side backup keys
await self.store.bulk_delete_backup_keys_and_versions_for_user(user_id)

# Let modules know the user has been deactivated.
await self._third_party_rules.on_user_deactivation_status_changed(
user_id,
Expand Down
26 changes: 26 additions & 0 deletions synapse/storage/databases/main/e2e_room_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,3 +550,29 @@ def _delete_e2e_room_keys_version_txn(txn: LoggingTransaction) -> None:
await self.db_pool.runInteraction(
"delete_e2e_room_keys_version", _delete_e2e_room_keys_version_txn
)

async def bulk_delete_backup_keys_and_versions_for_user(self, user_id: str) -> None:
"""
Bulk deletes all backup room keys and versions for a given user.

Args:
user_id: the user whose backup keys and versions we're deleting
"""

def _delete_all_e2e_room_keys_and_versions_txn(txn: LoggingTransaction) -> None:
self.db_pool.simple_delete_txn(
txn,
table="e2e_room_keys",
keyvalues={"user_id": user_id},
)

self.db_pool.simple_delete_txn(
txn,
table="e2e_room_keys_versions",
keyvalues={"user_id": user_id},
)

await self.db_pool.runInteraction(
"delete_all_e2e_room_keys_and_versions",
_delete_all_e2e_room_keys_and_versions_txn,
)
66 changes: 66 additions & 0 deletions tests/rest/client/test_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,72 @@ def test_pending_invites(self) -> None:
self.assertEqual(len(memberships), 1, memberships)
self.assertEqual(memberships[0].room_id, room_id, memberships)

def test_deactivate_account_deletes_server_side_backup_keys(self) -> None:
key_handler = self.hs.get_e2e_room_keys_handler()
room_keys = {
"rooms": {
"!abc:matrix.org": {
"sessions": {
"c0ff33": {
"first_message_index": 1,
"forwarded_count": 1,
"is_verified": False,
"session_data": "SSBBTSBBIEZJU0gK",
}
}
}
}
}

user_id = self.register_user("missPiggy", "test")
tok = self.login("missPiggy", "test")

# add some backup keys/versions
version = self.get_success(
key_handler.create_version(
user_id,
{
"algorithm": "m.megolm_backup.v1",
"auth_data": "first_version_auth_data",
},
)
)

self.get_success(key_handler.upload_room_keys(user_id, version, room_keys))

version2 = self.get_success(
key_handler.create_version(
user_id,
{
"algorithm": "m.megolm_backup.v1",
"auth_data": "second_version_auth_data",
},
)
)

self.get_success(key_handler.upload_room_keys(user_id, version2, room_keys))

self.deactivate(user_id, tok)
store = self.hs.get_datastores().main

# Check that the user has been marked as deactivated.
self.assertTrue(self.get_success(store.get_user_deactivated_status(user_id)))

# Check that there are no entries in 'e2e_room_keys` and `e2e_room_keys_versions`
res = self.get_success(
self.hs.get_datastores().main.db_pool.simple_select_list(
"e2e_room_keys", {"user_id": user_id}, "*", "simple_select"
)
)
self.assertEqual(len(res), 0)

res2 = self.get_success(
self.hs.get_datastores().main.db_pool.simple_select_list(
"e2e_room_keys_versions", {"user_id": user_id}, "*", "simple_select"
)
)
self.assertEqual(len(res2), 0)

def deactivate(self, user_id: str, tok: str) -> None:
request_data = {
"auth": {
Expand Down