This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
add etag and count to key backup endpoints #5858
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
84abdfd
add hash and count to key backup endpoints
uhoreg 049a939
add changelog
uhoreg a1b0cbc
fix formatting
uhoreg b0fd375
fix postgres compatibility
uhoreg 0355a75
Merge branch 'develop' into uhoreg/e2e_backup_hash
uhoreg d081883
add count and hash when deleting keys
uhoreg 72fb8ac
black
uhoreg e9d587d
Apply suggestions from code review
uhoreg 0dc4c4e
apply suggestions from PR review
uhoreg 438c839
black
uhoreg c75ad8a
Merge branch 'develop' into uhoreg/e2e_backup_hash
uhoreg f589390
fix merge conflict
uhoreg a5a59ab
Merge branch 'develop' into uhoreg/e2e_backup_hash
uhoreg 160f434
rename hash to etag, to match MSC
uhoreg 744d744
black
uhoreg 00fa0c9
update the changelog too
uhoreg 8721067
fix unit test to use new API
uhoreg a025746
PostgreSQL doesn't like INTEGER UNSIGNED
uhoreg 3991e78
drop unsigned
uhoreg 1e6e3e9
apply suggestions from review
uhoreg a2a3f75
Merge branch 'develop' into uhoreg/e2e_backup_hash
uhoreg 1e2d261
comment fixes
uhoreg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add etag and count fields to key backup endpoints to help clients guess if there are new keys. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
# Copyright 2017, 2018 New Vector Ltd | ||
# Copyright 2019 Matrix.org Foundation C.I.C. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
|
@@ -103,14 +104,35 @@ def delete_room_keys(self, user_id, version, room_id=None, session_id=None): | |
rooms | ||
session_id(string): session ID to delete keys for, for None to delete keys | ||
for all sessions | ||
Raises: | ||
NotFoundError: if the backup version does not exist | ||
Returns: | ||
A deferred of the deletion transaction | ||
A dict containing the count and etag for the backup version | ||
""" | ||
|
||
# lock for consistency with uploading | ||
with (yield self._upload_linearizer.queue(user_id)): | ||
# make sure the backup version exists | ||
try: | ||
version_info = yield self.store.get_e2e_room_keys_version_info( | ||
user_id, version | ||
) | ||
except StoreError as e: | ||
if e.code == 404: | ||
raise NotFoundError("Unknown backup version") | ||
else: | ||
raise | ||
|
||
yield self.store.delete_e2e_room_keys(user_id, version, room_id, session_id) | ||
|
||
version_etag = version_info["etag"] + 1 | ||
yield self.store.update_e2e_room_keys_version( | ||
user_id, version, None, version_etag | ||
) | ||
|
||
count = yield self.store.count_e2e_room_keys(user_id, version) | ||
return {"etag": str(version_etag), "count": count} | ||
|
||
@trace | ||
@defer.inlineCallbacks | ||
def upload_room_keys(self, user_id, version, room_keys): | ||
|
@@ -138,6 +160,9 @@ def upload_room_keys(self, user_id, version, room_keys): | |
} | ||
} | ||
|
||
Returns: | ||
A dict containing the count and etag for the backup version | ||
|
||
Raises: | ||
NotFoundError: if there are no versions defined | ||
RoomKeysVersionError: if the uploaded version is not the current version | ||
|
@@ -171,59 +196,62 @@ def upload_room_keys(self, user_id, version, room_keys): | |
else: | ||
raise | ||
|
||
# go through the room_keys. | ||
# XXX: this should/could be done concurrently, given we're in a lock. | ||
# Fetch any existing room keys for the sessions that have been | ||
# submitted. Then compare them with the submitted keys. If the | ||
# key is new, insert it; if the key should be updated, then update | ||
# it; otherwise, drop it. | ||
existing_keys = yield self.store.get_e2e_room_keys_multi( | ||
user_id, version, room_keys["rooms"] | ||
) | ||
to_insert = [] # batch the inserts together | ||
changed = False # if anything has changed, we need to update the etag | ||
for room_id, room in iteritems(room_keys["rooms"]): | ||
for session_id, session in iteritems(room["sessions"]): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, the diff gets hard to follow in this section, and it's much easier to just look at the file for this section. |
||
yield self._upload_room_key( | ||
user_id, version, room_id, session_id, session | ||
for session_id, room_key in iteritems(room["sessions"]): | ||
log_kv( | ||
{ | ||
"message": "Trying to upload room key", | ||
"room_id": room_id, | ||
"session_id": session_id, | ||
"user_id": user_id, | ||
} | ||
) | ||
|
||
@defer.inlineCallbacks | ||
def _upload_room_key(self, user_id, version, room_id, session_id, room_key): | ||
"""Upload a given room_key for a given room and session into a given | ||
version of the backup. Merges the key with any which might already exist. | ||
|
||
Args: | ||
user_id(str): the user whose backup we're setting | ||
version(str): the version ID of the backup we're updating | ||
room_id(str): the ID of the room whose keys we're setting | ||
session_id(str): the session whose room_key we're setting | ||
room_key(dict): the room_key being set | ||
""" | ||
log_kv( | ||
{ | ||
"message": "Trying to upload room key", | ||
"room_id": room_id, | ||
"session_id": session_id, | ||
"user_id": user_id, | ||
} | ||
) | ||
# get the room_key for this particular row | ||
current_room_key = None | ||
try: | ||
current_room_key = yield self.store.get_e2e_room_key( | ||
user_id, version, room_id, session_id | ||
) | ||
except StoreError as e: | ||
if e.code == 404: | ||
log_kv( | ||
{ | ||
"message": "Room key not found.", | ||
"room_id": room_id, | ||
"user_id": user_id, | ||
} | ||
current_room_key = existing_keys.get(room_id, {}).get(session_id) | ||
if current_room_key: | ||
if self._should_replace_room_key(current_room_key, room_key): | ||
log_kv({"message": "Replacing room key."}) | ||
# updates are done one at a time in the DB, so send | ||
# updates right away rather than batching them up, | ||
# like we do with the inserts | ||
yield self.store.update_e2e_room_key( | ||
user_id, version, room_id, session_id, room_key | ||
) | ||
changed = True | ||
else: | ||
log_kv({"message": "Not replacing room_key."}) | ||
else: | ||
log_kv( | ||
{ | ||
"message": "Room key not found.", | ||
"room_id": room_id, | ||
"user_id": user_id, | ||
} | ||
) | ||
log_kv({"message": "Replacing room key."}) | ||
to_insert.append((room_id, session_id, room_key)) | ||
changed = True | ||
|
||
if len(to_insert): | ||
yield self.store.add_e2e_room_keys(user_id, version, to_insert) | ||
|
||
version_etag = version_info["etag"] | ||
if changed: | ||
version_etag = version_etag + 1 | ||
yield self.store.update_e2e_room_keys_version( | ||
user_id, version, None, version_etag | ||
) | ||
else: | ||
raise | ||
|
||
if self._should_replace_room_key(current_room_key, room_key): | ||
log_kv({"message": "Replacing room key."}) | ||
yield self.store.set_e2e_room_key( | ||
user_id, version, room_id, session_id, room_key | ||
) | ||
else: | ||
log_kv({"message": "Not replacing room_key."}) | ||
count = yield self.store.count_e2e_room_keys(user_id, version) | ||
return {"etag": str(version_etag), "count": count} | ||
|
||
@staticmethod | ||
def _should_replace_room_key(current_room_key, room_key): | ||
|
@@ -314,6 +342,8 @@ def get_version_info(self, user_id, version=None): | |
raise NotFoundError("Unknown backup version") | ||
else: | ||
raise | ||
|
||
res["count"] = yield self.store.count_e2e_room_keys(user_id, res["version"]) | ||
return res | ||
|
||
@trace | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.