diff options
author | kegsay <kegan@matrix.org> | 2021-07-27 17:08:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-27 17:08:53 +0100 |
commit | b3754d68fcbe9022eb0bf4f8eda7102b7c27e62d (patch) | |
tree | fb289fc2baf56205292d0f0ce28c9f6924278b01 /userapi/internal/api.go | |
parent | a060df91e206903e4e3cbf7b7d2dabddfa0bf788 (diff) |
Key Backups (2/3) : Add E2E backup key tables (#1945)
* Add PUT key backup endpoints and glue them to PerformKeyBackup
* Add tables for storing backup keys and glue them into the user API
* Don't create tables whilst still WIPing
* writer on sqlite please
* Linting
Diffstat (limited to 'userapi/internal/api.go')
-rw-r--r-- | userapi/internal/api.go | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/userapi/internal/api.go b/userapi/internal/api.go index 9ff69298..27e17963 100644 --- a/userapi/internal/api.go +++ b/userapi/internal/api.go @@ -444,7 +444,7 @@ func (a *UserInternalAPI) QueryOpenIDToken(ctx context.Context, req *api.QueryOp } func (a *UserInternalAPI) PerformKeyBackup(ctx context.Context, req *api.PerformKeyBackupRequest, res *api.PerformKeyBackupResponse) { - // Delete + // Delete metadata if req.DeleteBackup { if req.Version == "" { res.BadInput = true @@ -459,7 +459,7 @@ func (a *UserInternalAPI) PerformKeyBackup(ctx context.Context, req *api.Perform res.Version = req.Version return } - // Create + // Create metadata if req.Version == "" { version, err := a.AccountDB.CreateKeyBackup(ctx, req.UserID, req.Algorithm, req.AuthData) if err != nil { @@ -469,16 +469,55 @@ func (a *UserInternalAPI) PerformKeyBackup(ctx context.Context, req *api.Perform res.Version = version return } - // Update - err := a.AccountDB.UpdateKeyBackupAuthData(ctx, req.UserID, req.Version, req.AuthData) + // Update metadata + if len(req.Keys.Rooms) == 0 { + err := a.AccountDB.UpdateKeyBackupAuthData(ctx, req.UserID, req.Version, req.AuthData) + if err != nil { + res.Error = fmt.Sprintf("failed to update backup: %s", err) + } + res.Version = req.Version + return + } + // Upload Keys for a specific version metadata + a.uploadBackupKeys(ctx, req, res) +} + +func (a *UserInternalAPI) uploadBackupKeys(ctx context.Context, req *api.PerformKeyBackupRequest, res *api.PerformKeyBackupResponse) { + // ensure the version metadata exists + version, _, _, _, deleted, err := a.AccountDB.GetKeyBackup(ctx, req.UserID, req.Version) if err != nil { - res.Error = fmt.Sprintf("failed to update backup: %s", err) + res.Error = fmt.Sprintf("failed to query version: %s", err) + return + } + if deleted { + res.Error = "backup was deleted" + return + } + res.Exists = true + res.Version = version + + // map keys to a form we can upload more easily - the map ensures we have no duplicates. + var uploads []api.InternalKeyBackupSession + for roomID, data := range req.Keys.Rooms { + for sessionID, sessionData := range data.Sessions { + uploads = append(uploads, api.InternalKeyBackupSession{ + RoomID: roomID, + SessionID: sessionID, + KeyBackupSession: sessionData, + }) + } + } + count, etag, err := a.AccountDB.UpsertBackupKeys(ctx, version, req.UserID, uploads) + if err != nil { + res.Error = fmt.Sprintf("failed to upsert keys: %s", err) + return } - res.Version = req.Version + res.KeyCount = count + res.KeyETag = etag } func (a *UserInternalAPI) QueryKeyBackup(ctx context.Context, req *api.QueryKeyBackupRequest, res *api.QueryKeyBackupResponse) { - version, algorithm, authData, deleted, err := a.AccountDB.GetKeyBackup(ctx, req.UserID, req.Version) + version, algorithm, authData, etag, deleted, err := a.AccountDB.GetKeyBackup(ctx, req.UserID, req.Version) res.Version = version if err != nil { if err == sql.ErrNoRows { @@ -494,5 +533,5 @@ func (a *UserInternalAPI) QueryKeyBackup(ctx context.Context, req *api.QueryKeyB // TODO: res.Count = 0 - res.ETag = "" + res.ETag = etag } |