aboutsummaryrefslogtreecommitdiff
path: root/roomserver
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-06-29 15:29:39 +0100
committerGitHub <noreply@github.com>2022-06-29 15:29:39 +0100
commit519bc1124b051273019aae9b11617ebd796e962f (patch)
tree63445e1384d880e2ab94a1847f6a11553f822547 /roomserver
parent2dea466685d0d4ab74d4cbd84af16b621d1269b3 (diff)
Add `evacuateUser` endpoint, use it when deactivating accounts (#2545)
* Add `evacuateUser` endpoint, use it when deactivating accounts * Populate the API * Clean up user devices when deactivating * Include invites, delete pushers
Diffstat (limited to 'roomserver')
-rw-r--r--roomserver/api/api.go8
-rw-r--r--roomserver/api/api_trace.go9
-rw-r--r--roomserver/api/perform.go9
-rw-r--r--roomserver/internal/api.go1
-rw-r--r--roomserver/internal/perform/perform_admin.go70
-rw-r--r--roomserver/inthttp/client.go18
-rw-r--r--roomserver/inthttp/server.go11
7 files changed, 121 insertions, 5 deletions
diff --git a/roomserver/api/api.go b/roomserver/api/api.go
index f87ff296..38baa617 100644
--- a/roomserver/api/api.go
+++ b/roomserver/api/api.go
@@ -140,11 +140,8 @@ type ClientRoomserverAPI interface {
// PerformRoomUpgrade upgrades a room to a newer version
PerformRoomUpgrade(ctx context.Context, req *PerformRoomUpgradeRequest, resp *PerformRoomUpgradeResponse)
- PerformAdminEvacuateRoom(
- ctx context.Context,
- req *PerformAdminEvacuateRoomRequest,
- res *PerformAdminEvacuateRoomResponse,
- )
+ PerformAdminEvacuateRoom(ctx context.Context, req *PerformAdminEvacuateRoomRequest, res *PerformAdminEvacuateRoomResponse)
+ PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse)
PerformPeek(ctx context.Context, req *PerformPeekRequest, res *PerformPeekResponse)
PerformUnpeek(ctx context.Context, req *PerformUnpeekRequest, res *PerformUnpeekResponse)
PerformInvite(ctx context.Context, req *PerformInviteRequest, res *PerformInviteResponse) error
@@ -161,6 +158,7 @@ type UserRoomserverAPI interface {
QueryLatestEventsAndStateAPI
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
+ PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse)
}
type FederationRoomserverAPI interface {
diff --git a/roomserver/api/api_trace.go b/roomserver/api/api_trace.go
index 92c5c1b1..211f320f 100644
--- a/roomserver/api/api_trace.go
+++ b/roomserver/api/api_trace.go
@@ -113,6 +113,15 @@ func (t *RoomserverInternalAPITrace) PerformAdminEvacuateRoom(
util.GetLogger(ctx).Infof("PerformAdminEvacuateRoom req=%+v res=%+v", js(req), js(res))
}
+func (t *RoomserverInternalAPITrace) PerformAdminEvacuateUser(
+ ctx context.Context,
+ req *PerformAdminEvacuateUserRequest,
+ res *PerformAdminEvacuateUserResponse,
+) {
+ t.Impl.PerformAdminEvacuateUser(ctx, req, res)
+ util.GetLogger(ctx).Infof("PerformAdminEvacuateUser req=%+v res=%+v", js(req), js(res))
+}
+
func (t *RoomserverInternalAPITrace) PerformInboundPeek(
ctx context.Context,
req *PerformInboundPeekRequest,
diff --git a/roomserver/api/perform.go b/roomserver/api/perform.go
index 30aa2cf1..d9ea9dd1 100644
--- a/roomserver/api/perform.go
+++ b/roomserver/api/perform.go
@@ -223,3 +223,12 @@ type PerformAdminEvacuateRoomResponse struct {
Affected []string `json:"affected"`
Error *PerformError
}
+
+type PerformAdminEvacuateUserRequest struct {
+ UserID string `json:"user_id"`
+}
+
+type PerformAdminEvacuateUserResponse struct {
+ Affected []string `json:"affected"`
+ Error *PerformError
+}
diff --git a/roomserver/internal/api.go b/roomserver/internal/api.go
index afef52da..acdaeef6 100644
--- a/roomserver/internal/api.go
+++ b/roomserver/internal/api.go
@@ -170,6 +170,7 @@ func (r *RoomserverInternalAPI) SetFederationAPI(fsAPI fsAPI.RoomserverFederatio
Cfg: r.Cfg,
Inputer: r.Inputer,
Queryer: r.Queryer,
+ Leaver: r.Leaver,
}
if err := r.Inputer.Start(); err != nil {
diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go
index 2de6477c..d3fb7109 100644
--- a/roomserver/internal/perform/perform_admin.go
+++ b/roomserver/internal/perform/perform_admin.go
@@ -16,6 +16,7 @@ package perform
import (
"context"
+ "database/sql"
"encoding/json"
"fmt"
"time"
@@ -34,6 +35,7 @@ type Admin struct {
Cfg *config.RoomServer
Queryer *query.Queryer
Inputer *input.Inputer
+ Leaver *Leaver
}
// PerformEvacuateRoom will remove all local users from the given room.
@@ -160,3 +162,71 @@ func (r *Admin) PerformAdminEvacuateRoom(
inputRes := &api.InputRoomEventsResponse{}
r.Inputer.InputRoomEvents(ctx, inputReq, inputRes)
}
+
+func (r *Admin) PerformAdminEvacuateUser(
+ ctx context.Context,
+ req *api.PerformAdminEvacuateUserRequest,
+ res *api.PerformAdminEvacuateUserResponse,
+) {
+ _, domain, err := gomatrixserverlib.SplitID('@', req.UserID)
+ if err != nil {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("Malformed user ID: %s", err),
+ }
+ return
+ }
+ if domain != r.Cfg.Matrix.ServerName {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: "Can only evacuate local users using this endpoint",
+ }
+ return
+ }
+
+ roomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, gomatrixserverlib.Join)
+ if err != nil && err != sql.ErrNoRows {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
+ }
+ return
+ }
+
+ inviteRoomIDs, err := r.DB.GetRoomsByMembership(ctx, req.UserID, gomatrixserverlib.Invite)
+ if err != nil && err != sql.ErrNoRows {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("r.DB.GetRoomsByMembership: %s", err),
+ }
+ return
+ }
+
+ for _, roomID := range append(roomIDs, inviteRoomIDs...) {
+ leaveReq := &api.PerformLeaveRequest{
+ RoomID: roomID,
+ UserID: req.UserID,
+ }
+ leaveRes := &api.PerformLeaveResponse{}
+ outputEvents, err := r.Leaver.PerformLeave(ctx, leaveReq, leaveRes)
+ if err != nil {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("r.Leaver.PerformLeave: %s", err),
+ }
+ return
+ }
+ if len(outputEvents) == 0 {
+ continue
+ }
+ if err := r.Inputer.WriteOutputEvents(roomID, outputEvents); err != nil {
+ res.Error = &api.PerformError{
+ Code: api.PerformErrorBadRequest,
+ Msg: fmt.Sprintf("r.Inputer.WriteOutputEvents: %s", err),
+ }
+ return
+ }
+
+ res.Affected = append(res.Affected, roomID)
+ }
+}
diff --git a/roomserver/inthttp/client.go b/roomserver/inthttp/client.go
index 7b10ae65..2fa8afc4 100644
--- a/roomserver/inthttp/client.go
+++ b/roomserver/inthttp/client.go
@@ -40,6 +40,7 @@ const (
RoomserverPerformInboundPeekPath = "/roomserver/performInboundPeek"
RoomserverPerformForgetPath = "/roomserver/performForget"
RoomserverPerformAdminEvacuateRoomPath = "/roomserver/performAdminEvacuateRoom"
+ RoomserverPerformAdminEvacuateUserPath = "/roomserver/performAdminEvacuateUser"
// Query operations
RoomserverQueryLatestEventsAndStatePath = "/roomserver/queryLatestEventsAndState"
@@ -305,6 +306,23 @@ func (h *httpRoomserverInternalAPI) PerformAdminEvacuateRoom(
}
}
+func (h *httpRoomserverInternalAPI) PerformAdminEvacuateUser(
+ ctx context.Context,
+ req *api.PerformAdminEvacuateUserRequest,
+ res *api.PerformAdminEvacuateUserResponse,
+) {
+ span, ctx := opentracing.StartSpanFromContext(ctx, "PerformAdminEvacuateUser")
+ defer span.Finish()
+
+ apiURL := h.roomserverURL + RoomserverPerformAdminEvacuateUserPath
+ err := httputil.PostJSON(ctx, span, h.httpClient, apiURL, req, res)
+ if err != nil {
+ res.Error = &api.PerformError{
+ Msg: fmt.Sprintf("failed to communicate with roomserver: %s", err),
+ }
+ }
+}
+
// QueryLatestEventsAndState implements RoomserverQueryAPI
func (h *httpRoomserverInternalAPI) QueryLatestEventsAndState(
ctx context.Context,
diff --git a/roomserver/inthttp/server.go b/roomserver/inthttp/server.go
index ad4fdc46..99338158 100644
--- a/roomserver/inthttp/server.go
+++ b/roomserver/inthttp/server.go
@@ -129,6 +129,17 @@ func AddRoutes(r api.RoomserverInternalAPI, internalAPIMux *mux.Router) {
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
}),
)
+ internalAPIMux.Handle(RoomserverPerformAdminEvacuateUserPath,
+ httputil.MakeInternalAPI("performAdminEvacuateUser", func(req *http.Request) util.JSONResponse {
+ var request api.PerformAdminEvacuateUserRequest
+ var response api.PerformAdminEvacuateUserResponse
+ if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
+ return util.MessageResponse(http.StatusBadRequest, err.Error())
+ }
+ r.PerformAdminEvacuateUser(req.Context(), &request, &response)
+ return util.JSONResponse{Code: http.StatusOK, JSON: &response}
+ }),
+ )
internalAPIMux.Handle(
RoomserverQueryPublishedRoomsPath,
httputil.MakeInternalAPI("queryPublishedRooms", func(req *http.Request) util.JSONResponse {