diff --git a/clientapi/routing/device.go b/clientapi/routing/device.go index 01310400a..11c6c7827 100644 --- a/clientapi/routing/device.go +++ b/clientapi/routing/device.go @@ -165,7 +165,7 @@ func UpdateDeviceByID( // DeleteDeviceById handles DELETE requests to /devices/{deviceId} func DeleteDeviceById( - req *http.Request, userInteractiveAuth *auth.UserInteractive, deviceDB devices.Database, device *api.Device, + req *http.Request, userInteractiveAuth *auth.UserInteractive, userAPI api.UserInternalAPI, device *api.Device, deviceID string, ) util.JSONResponse { ctx := req.Context() @@ -197,8 +197,12 @@ func DeleteDeviceById( } } - if err := deviceDB.RemoveDevice(ctx, deviceID, localpart); err != nil { - util.GetLogger(ctx).WithError(err).Error("deviceDB.RemoveDevice failed") + var res api.PerformDeviceDeletionResponse + if err := userAPI.PerformDeviceDeletion(ctx, &api.PerformDeviceDeletionRequest{ + UserID: device.UserID, + DeviceIDs: []string{deviceID}, + }, &res); err != nil { + util.GetLogger(ctx).WithError(err).Error("userAPI.PerformDeviceDeletion failed") return jsonerror.InternalServerError() } @@ -210,26 +214,24 @@ func DeleteDeviceById( // DeleteDevices handles POST requests to /delete_devices func DeleteDevices( - req *http.Request, deviceDB devices.Database, device *api.Device, + req *http.Request, userAPI api.UserInternalAPI, device *api.Device, ) util.JSONResponse { - localpart, _, err := gomatrixserverlib.SplitID('@', device.UserID) - if err != nil { - util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed") - return jsonerror.InternalServerError() - } - ctx := req.Context() payload := devicesDeleteJSON{} if err := json.NewDecoder(req.Body).Decode(&payload); err != nil { - util.GetLogger(req.Context()).WithError(err).Error("json.NewDecoder.Decode failed") + util.GetLogger(ctx).WithError(err).Error("json.NewDecoder.Decode failed") return jsonerror.InternalServerError() } defer req.Body.Close() // nolint: errcheck - if err := deviceDB.RemoveDevices(ctx, localpart, payload.Devices); err != nil { - util.GetLogger(req.Context()).WithError(err).Error("deviceDB.RemoveDevices failed") + var res api.PerformDeviceDeletionResponse + if err := userAPI.PerformDeviceDeletion(ctx, &api.PerformDeviceDeletionRequest{ + UserID: device.UserID, + DeviceIDs: payload.Devices, + }, &res); err != nil { + util.GetLogger(ctx).WithError(err).Error("userAPI.PerformDeviceDeletion failed") return jsonerror.InternalServerError() } diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index ebb141ef8..6c40db865 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -654,13 +654,13 @@ func Setup( if err != nil { return util.ErrorResponse(err) } - return DeleteDeviceById(req, userInteractiveAuth, deviceDB, device, vars["deviceID"]) + return DeleteDeviceById(req, userInteractiveAuth, userAPI, device, vars["deviceID"]) }), ).Methods(http.MethodDelete, http.MethodOptions) r0mux.Handle("/delete_devices", httputil.MakeAuthAPI("delete_devices", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { - return DeleteDevices(req, deviceDB, device) + return DeleteDevices(req, userAPI, device) }), ).Methods(http.MethodPost, http.MethodOptions) diff --git a/userapi/api/api.go b/userapi/api/api.go index 5791403ff..5c964c4fd 100644 --- a/userapi/api/api.go +++ b/userapi/api/api.go @@ -27,6 +27,7 @@ type UserInternalAPI interface { InputAccountData(ctx context.Context, req *InputAccountDataRequest, res *InputAccountDataResponse) error PerformAccountCreation(ctx context.Context, req *PerformAccountCreationRequest, res *PerformAccountCreationResponse) error PerformDeviceCreation(ctx context.Context, req *PerformDeviceCreationRequest, res *PerformDeviceCreationResponse) error + PerformDeviceDeletion(ctx context.Context, req *PerformDeviceDeletionRequest, res *PerformDeviceDeletionResponse) error QueryProfile(ctx context.Context, req *QueryProfileRequest, res *QueryProfileResponse) error QueryAccessToken(ctx context.Context, req *QueryAccessTokenRequest, res *QueryAccessTokenResponse) error QueryDevices(ctx context.Context, req *QueryDevicesRequest, res *QueryDevicesResponse) error @@ -47,6 +48,15 @@ type InputAccountDataRequest struct { type InputAccountDataResponse struct { } +type PerformDeviceDeletionRequest struct { + UserID string + // The devices to delete + DeviceIDs []string +} + +type PerformDeviceDeletionResponse struct { +} + // QueryDeviceInfosRequest is the request to QueryDeviceInfos type QueryDeviceInfosRequest struct { DeviceIDs []string diff --git a/userapi/internal/api.go b/userapi/internal/api.go index 5b1541967..7ffc18013 100644 --- a/userapi/internal/api.go +++ b/userapi/internal/api.go @@ -104,6 +104,17 @@ func (a *UserInternalAPI) PerformDeviceCreation(ctx context.Context, req *api.Pe return nil } +func (a *UserInternalAPI) PerformDeviceDeletion(ctx context.Context, req *api.PerformDeviceDeletionRequest, res *api.PerformDeviceDeletionResponse) error { + local, domain, err := gomatrixserverlib.SplitID('@', req.UserID) + if err != nil { + return err + } + if domain != a.ServerName { + return fmt.Errorf("cannot PerformDeviceDeletion of remote users: got %s want %s", domain, a.ServerName) + } + return a.DeviceDB.RemoveDevices(ctx, local, req.DeviceIDs) +} + func (a *UserInternalAPI) QueryProfile(ctx context.Context, req *api.QueryProfileRequest, res *api.QueryProfileResponse) error { local, domain, err := gomatrixserverlib.SplitID('@', req.UserID) if err != nil { diff --git a/userapi/inthttp/client.go b/userapi/inthttp/client.go index 3e1ac0662..47e2110f9 100644 --- a/userapi/inthttp/client.go +++ b/userapi/inthttp/client.go @@ -30,6 +30,7 @@ const ( PerformDeviceCreationPath = "/userapi/performDeviceCreation" PerformAccountCreationPath = "/userapi/performAccountCreation" + PerformDeviceDeletionPath = "/userapi/performDeviceDeletion" QueryProfilePath = "/userapi/queryProfile" QueryAccessTokenPath = "/userapi/queryAccessToken" @@ -91,6 +92,18 @@ func (h *httpUserInternalAPI) PerformDeviceCreation( return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) } +func (h *httpUserInternalAPI) PerformDeviceDeletion( + ctx context.Context, + request *api.PerformDeviceDeletionRequest, + response *api.PerformDeviceDeletionResponse, +) error { + span, ctx := opentracing.StartSpanFromContext(ctx, "PerformDeviceDeletion") + defer span.Finish() + + apiURL := h.apiURL + PerformDeviceDeletionPath + return httputil.PostJSON(ctx, span, h.httpClient, apiURL, request, response) +} + func (h *httpUserInternalAPI) QueryProfile( ctx context.Context, request *api.QueryProfileRequest, diff --git a/userapi/inthttp/server.go b/userapi/inthttp/server.go index d29f4d442..ebb9bf4e8 100644 --- a/userapi/inthttp/server.go +++ b/userapi/inthttp/server.go @@ -52,6 +52,19 @@ func AddRoutes(internalAPIMux *mux.Router, s api.UserInternalAPI) { return util.JSONResponse{Code: http.StatusOK, JSON: &response} }), ) + internalAPIMux.Handle(PerformDeviceDeletionPath, + httputil.MakeInternalAPI("performDeviceDeletion", func(req *http.Request) util.JSONResponse { + request := api.PerformDeviceDeletionRequest{} + response := api.PerformDeviceDeletionResponse{} + if err := json.NewDecoder(req.Body).Decode(&request); err != nil { + return util.MessageResponse(http.StatusBadRequest, err.Error()) + } + if err := s.PerformDeviceDeletion(req.Context(), &request, &response); err != nil { + return util.ErrorResponse(err) + } + return util.JSONResponse{Code: http.StatusOK, JSON: &response} + }), + ) internalAPIMux.Handle(QueryProfilePath, httputil.MakeInternalAPI("queryProfile", func(req *http.Request) util.JSONResponse { request := api.QueryProfileRequest{}