diff options
author | Neil Alexander <neilalexander@users.noreply.github.com> | 2022-06-29 15:29:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-29 15:29:39 +0100 |
commit | 519bc1124b051273019aae9b11617ebd796e962f (patch) | |
tree | 63445e1384d880e2ab94a1847f6a11553f822547 /roomserver | |
parent | 2dea466685d0d4ab74d4cbd84af16b621d1269b3 (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.go | 8 | ||||
-rw-r--r-- | roomserver/api/api_trace.go | 9 | ||||
-rw-r--r-- | roomserver/api/perform.go | 9 | ||||
-rw-r--r-- | roomserver/internal/api.go | 1 | ||||
-rw-r--r-- | roomserver/internal/perform/perform_admin.go | 70 | ||||
-rw-r--r-- | roomserver/inthttp/client.go | 18 | ||||
-rw-r--r-- | roomserver/inthttp/server.go | 11 |
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 { |