aboutsummaryrefslogtreecommitdiff
path: root/clientapi/routing/key_backup.go
diff options
context:
space:
mode:
authorkegsay <kegan@matrix.org>2021-07-27 12:47:32 +0100
committerGitHub <noreply@github.com>2021-07-27 12:47:32 +0100
commit32538640db6bfbdb890729e8137151ffbbec9a28 (patch)
treebcd98d8b0d977058492fce03d69f43cc3a41be51 /clientapi/routing/key_backup.go
parente3679799ea6f6387d36fb1a2f938f8ea9711ad2d (diff)
Key backups (1/2) : Add E2E session backup metadata tables (#1943)
* Initial key backup paths and userapi API * Fix unit tests * Add key backup table * Glue REST API to database * Linting * use writer on sqlite
Diffstat (limited to 'clientapi/routing/key_backup.go')
-rw-r--r--clientapi/routing/key_backup.go173
1 files changed, 173 insertions, 0 deletions
diff --git a/clientapi/routing/key_backup.go b/clientapi/routing/key_backup.go
new file mode 100644
index 00000000..0aa73624
--- /dev/null
+++ b/clientapi/routing/key_backup.go
@@ -0,0 +1,173 @@
+// Copyright 2021 The 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.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package routing
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+
+ "github.com/matrix-org/dendrite/clientapi/httputil"
+ "github.com/matrix-org/dendrite/clientapi/jsonerror"
+ userapi "github.com/matrix-org/dendrite/userapi/api"
+ "github.com/matrix-org/util"
+)
+
+type keyBackupVersion struct {
+ Algorithm string `json:"algorithm"`
+ AuthData json.RawMessage `json:"auth_data"`
+}
+
+type keyBackupVersionCreateResponse struct {
+ Version string `json:"version"`
+}
+
+type keyBackupVersionResponse struct {
+ Algorithm string `json:"algorithm"`
+ AuthData json.RawMessage `json:"auth_data"`
+ Count int `json:"count"`
+ ETag string `json:"etag"`
+ Version string `json:"version"`
+}
+
+// Create a new key backup. Request must contain a `keyBackupVersion`. Returns a `keyBackupVersionCreateResponse`.
+// Implements POST /_matrix/client/r0/room_keys/version
+func CreateKeyBackupVersion(req *http.Request, userAPI userapi.UserInternalAPI, device *userapi.Device) util.JSONResponse {
+ var kb keyBackupVersion
+ resErr := httputil.UnmarshalJSONRequest(req, &kb)
+ if resErr != nil {
+ return *resErr
+ }
+ var performKeyBackupResp userapi.PerformKeyBackupResponse
+ userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
+ UserID: device.UserID,
+ Version: "",
+ AuthData: kb.AuthData,
+ Algorithm: kb.Algorithm,
+ }, &performKeyBackupResp)
+ if performKeyBackupResp.Error != "" {
+ if performKeyBackupResp.BadInput {
+ return util.JSONResponse{
+ Code: 400,
+ JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
+ }
+ }
+ return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
+ }
+ return util.JSONResponse{
+ Code: 200,
+ JSON: keyBackupVersionCreateResponse{
+ Version: performKeyBackupResp.Version,
+ },
+ }
+}
+
+// KeyBackupVersion returns the key backup version specified. If `version` is empty, the latest `keyBackupVersionResponse` is returned.
+// Implements GET /_matrix/client/r0/room_keys/version and GET /_matrix/client/r0/room_keys/version/{version}
+func KeyBackupVersion(req *http.Request, userAPI userapi.UserInternalAPI, device *userapi.Device, version string) util.JSONResponse {
+ var queryResp userapi.QueryKeyBackupResponse
+ userAPI.QueryKeyBackup(req.Context(), &userapi.QueryKeyBackupRequest{}, &queryResp)
+ if queryResp.Error != "" {
+ return util.ErrorResponse(fmt.Errorf("QueryKeyBackup: %s", queryResp.Error))
+ }
+ if !queryResp.Exists {
+ return util.JSONResponse{
+ Code: 404,
+ JSON: jsonerror.NotFound("version not found"),
+ }
+ }
+ return util.JSONResponse{
+ Code: 200,
+ JSON: keyBackupVersionResponse{
+ Algorithm: queryResp.Algorithm,
+ AuthData: queryResp.AuthData,
+ Count: queryResp.Count,
+ ETag: queryResp.ETag,
+ Version: queryResp.Version,
+ },
+ }
+}
+
+// Modify the auth data of a key backup. Version must not be empty. Request must contain a `keyBackupVersion`
+// Implements PUT /_matrix/client/r0/room_keys/version/{version}
+func ModifyKeyBackupVersionAuthData(req *http.Request, userAPI userapi.UserInternalAPI, device *userapi.Device, version string) util.JSONResponse {
+ var kb keyBackupVersion
+ resErr := httputil.UnmarshalJSONRequest(req, &kb)
+ if resErr != nil {
+ return *resErr
+ }
+ var performKeyBackupResp userapi.PerformKeyBackupResponse
+ userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
+ UserID: device.UserID,
+ Version: version,
+ AuthData: kb.AuthData,
+ Algorithm: kb.Algorithm,
+ }, &performKeyBackupResp)
+ if performKeyBackupResp.Error != "" {
+ if performKeyBackupResp.BadInput {
+ return util.JSONResponse{
+ Code: 400,
+ JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
+ }
+ }
+ return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
+ }
+ if !performKeyBackupResp.Exists {
+ return util.JSONResponse{
+ Code: 404,
+ JSON: jsonerror.NotFound("backup version not found"),
+ }
+ }
+ // Unclear what the 200 body should be
+ return util.JSONResponse{
+ Code: 200,
+ JSON: keyBackupVersionCreateResponse{
+ Version: performKeyBackupResp.Version,
+ },
+ }
+}
+
+// Delete a version of key backup. Version must not be empty. If the key backup was previously deleted, will return 200 OK.
+// Implements DELETE /_matrix/client/r0/room_keys/version/{version}
+func DeleteKeyBackupVersion(req *http.Request, userAPI userapi.UserInternalAPI, device *userapi.Device, version string) util.JSONResponse {
+ var performKeyBackupResp userapi.PerformKeyBackupResponse
+ userAPI.PerformKeyBackup(req.Context(), &userapi.PerformKeyBackupRequest{
+ UserID: device.UserID,
+ Version: version,
+ DeleteBackup: true,
+ }, &performKeyBackupResp)
+ if performKeyBackupResp.Error != "" {
+ if performKeyBackupResp.BadInput {
+ return util.JSONResponse{
+ Code: 400,
+ JSON: jsonerror.InvalidArgumentValue(performKeyBackupResp.Error),
+ }
+ }
+ return util.ErrorResponse(fmt.Errorf("PerformKeyBackup: %s", performKeyBackupResp.Error))
+ }
+ if !performKeyBackupResp.Exists {
+ return util.JSONResponse{
+ Code: 404,
+ JSON: jsonerror.NotFound("backup version not found"),
+ }
+ }
+ // Unclear what the 200 body should be
+ return util.JSONResponse{
+ Code: 200,
+ JSON: keyBackupVersionCreateResponse{
+ Version: performKeyBackupResp.Version,
+ },
+ }
+}