mirror of
https://github.com/element-hq/dendrite.git
synced 2026-01-11 19:46:30 +00:00
Add admin endpoint to query empty rooms (#3663)
Some checks failed
Dendrite / WASM build test (push) Has been cancelled
Dendrite / Linting (push) Has been cancelled
Dendrite / Unit tests (push) Has been cancelled
Dendrite / Build for Linux (push) Has been cancelled
Dendrite / Build for Windows (push) Has been cancelled
Dendrite / Sytest (SQLite Cgo) (push) Has been cancelled
Dendrite / Initial tests passed (push) Has been cancelled
Dendrite / Integration tests (push) Has been cancelled
Dendrite / Upgrade tests (push) Has been cancelled
Dendrite / Upgrade tests from HEAD-2 (push) Has been cancelled
Dendrite / Sytest (PostgreSQL) (push) Has been cancelled
Dendrite / Sytest (SQLite native) (push) Has been cancelled
Dendrite / Complement (PostgreSQL) (push) Has been cancelled
Dendrite / Update Docker images (push) Has been cancelled
Dendrite / Complement (SQLite native) (push) Has been cancelled
Dendrite / Complement (SQLite Cgo) (push) Has been cancelled
Dendrite / Integration tests passed (push) Has been cancelled
Some checks failed
Dendrite / WASM build test (push) Has been cancelled
Dendrite / Linting (push) Has been cancelled
Dendrite / Unit tests (push) Has been cancelled
Dendrite / Build for Linux (push) Has been cancelled
Dendrite / Build for Windows (push) Has been cancelled
Dendrite / Sytest (SQLite Cgo) (push) Has been cancelled
Dendrite / Initial tests passed (push) Has been cancelled
Dendrite / Integration tests (push) Has been cancelled
Dendrite / Upgrade tests (push) Has been cancelled
Dendrite / Upgrade tests from HEAD-2 (push) Has been cancelled
Dendrite / Sytest (PostgreSQL) (push) Has been cancelled
Dendrite / Sytest (SQLite native) (push) Has been cancelled
Dendrite / Complement (PostgreSQL) (push) Has been cancelled
Dendrite / Update Docker images (push) Has been cancelled
Dendrite / Complement (SQLite native) (push) Has been cancelled
Dendrite / Complement (SQLite Cgo) (push) Has been cancelled
Dendrite / Integration tests passed (push) Has been cancelled
This is to complement the existing [Purge Room Admin API](https://element-hq.github.io/dendrite/administration/adminapi#post-_dendriteadminpurgeroomroomid) ### Pull Request Checklist <!-- Please read https://matrix-org.github.io/dendrite/development/contributing before submitting your pull request --> * [x] I have added Go unit tests or [Complement integration tests](https://github.com/matrix-org/complement) for this PR _or_ I have justified why this PR doesn't need tests * [x] Pull request includes a [sign off below](https://element-hq.github.io/dendrite/development/contributing#sign-off) _or_ I have already signed off privately --------- Signed-off-by: Till Faelligen <2353100+S7evinK@users.noreply.github.com>
This commit is contained in:
parent
68458c139d
commit
a042861df5
9 changed files with 111 additions and 2 deletions
|
|
@ -73,7 +73,7 @@ func AdminCreateNewRegistrationToken(req *http.Request, cfg *config.ClientAPI, u
|
|||
}
|
||||
|
||||
if len(token) > 64 {
|
||||
//Token present in request body, but is too long.
|
||||
// Token present in request body, but is too long.
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: spec.BadJSON("token must not be longer than 64"),
|
||||
|
|
@ -578,6 +578,23 @@ func DeleteEventReport(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAP
|
|||
}
|
||||
}
|
||||
|
||||
func QueryEmptyRooms(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAPI) util.JSONResponse {
|
||||
emptyRooms, err := rsAPI.AdminQueryEmptyRooms(req.Context())
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("failed to query empty rooms")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: spec.InternalServerError{},
|
||||
}
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: map[string]any{
|
||||
"empty_rooms": emptyRooms,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func parseUint64OrDefault(input string, defaultValue uint64) uint64 {
|
||||
v, err := strconv.ParseUint(input, 10, 64)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -243,6 +243,12 @@ func Setup(
|
|||
}),
|
||||
).Methods(http.MethodPost, http.MethodOptions)
|
||||
|
||||
dendriteAdminRouter.Handle("/admin/emptyRooms",
|
||||
httputil.MakeAdminAPI("admin_empty_rooms", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||
return QueryEmptyRooms(req, rsAPI)
|
||||
}),
|
||||
).Methods(http.MethodGet, http.MethodOptions)
|
||||
|
||||
// server notifications
|
||||
if cfg.Matrix.ServerNotices.Enabled {
|
||||
logrus.Info("Enabling server notices at /_synapse/admin/v1/send_server_notice")
|
||||
|
|
|
|||
|
|
@ -77,6 +77,19 @@ This endpoint instructs Dendrite to immediately query `/devices/{userID}` on a f
|
|||
|
||||
This endpoint instructs Dendrite to remove the given room from its database. It does **NOT** remove media files. Depending on the size of the room, this may take a while. Will return an empty JSON once other components were instructed to delete the room.
|
||||
|
||||
## GET `/_dendrite/admin/emptyRooms`
|
||||
|
||||
Returns a list of all rooms which have zero (locally) joined members. Response format:
|
||||
|
||||
```json
|
||||
{
|
||||
"empty_rooms": [
|
||||
"!roomid1:server_name",
|
||||
"!roomid2:server_name"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## POST `/_synapse/admin/v1/send_server_notice`
|
||||
|
||||
Request body format:
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ type RoomserverInternalAPI interface {
|
|||
|
||||
// RoomsWithACLs returns all room IDs for rooms with ACLs
|
||||
RoomsWithACLs(ctx context.Context) ([]string, error)
|
||||
// EmptyRooms returns all rooms that the local server has left.
|
||||
EmptyRooms(ctx context.Context) ([]string, error)
|
||||
}
|
||||
|
||||
type UserRoomPrivateKeyCreator interface {
|
||||
|
|
@ -248,6 +250,7 @@ type ClientRoomserverAPI interface {
|
|||
PerformAdminEvacuateUser(ctx context.Context, userID string) (affected []string, err error)
|
||||
PerformAdminPurgeRoom(ctx context.Context, roomID string) error
|
||||
PerformAdminDownloadState(ctx context.Context, roomID, userID string, serverName spec.ServerName) error
|
||||
AdminQueryEmptyRooms(ctx context.Context) ([]string, error)
|
||||
PerformPeek(ctx context.Context, req *PerformPeekRequest) (roomID string, err error)
|
||||
PerformUnpeek(ctx context.Context, roomID, userID, deviceID string) error
|
||||
PerformInvite(ctx context.Context, req *PerformInviteRequest) error
|
||||
|
|
@ -263,7 +266,7 @@ type ClientRoomserverAPI interface {
|
|||
// If true, then the alias has not been set to the provided room, as it already in use.
|
||||
SetRoomAlias(ctx context.Context, senderID spec.SenderID, roomID spec.RoomID, alias string) (aliasAlreadyExists bool, err error)
|
||||
|
||||
//RemoveRoomAlias(ctx context.Context, req *RemoveRoomAliasRequest, res *RemoveRoomAliasResponse) error
|
||||
// RemoveRoomAlias(ctx context.Context, req *RemoveRoomAliasRequest, res *RemoveRoomAliasResponse) error
|
||||
// Removes a room alias, as provided sender.
|
||||
//
|
||||
// Returns whether the alias was found, whether it was removed, and an error (if any occurred)
|
||||
|
|
|
|||
|
|
@ -350,3 +350,7 @@ func (r *Admin) PerformAdminDownloadState(
|
|||
func (r *Admin) PerformAdminDeleteEventReport(ctx context.Context, reportID uint64) error {
|
||||
return r.DB.AdminDeleteEventReport(ctx, reportID)
|
||||
}
|
||||
|
||||
func (r *Admin) AdminQueryEmptyRooms(ctx context.Context) ([]string, error) {
|
||||
return r.DB.EmptyRooms(ctx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1097,6 +1097,11 @@ func (r *Queryer) RoomsWithACLs(ctx context.Context) ([]string, error) {
|
|||
return r.DB.RoomsWithACLs(ctx)
|
||||
}
|
||||
|
||||
// EmptyRooms returns all rooms that the local server has left.
|
||||
func (r *Queryer) EmptyRooms(ctx context.Context) ([]string, error) {
|
||||
return r.DB.EmptyRooms(ctx)
|
||||
}
|
||||
|
||||
// QueryAdminEventReports returns event reports given a filter.
|
||||
func (r *Queryer) QueryAdminEventReports(ctx context.Context, from uint64, limit uint64, backwards bool, userID, roomID string) ([]api.QueryAdminEventReportsResponse, int64, error) {
|
||||
return r.DB.QueryAdminEventReports(ctx, from, limit, backwards, userID, roomID)
|
||||
|
|
|
|||
|
|
@ -1319,3 +1319,35 @@ func TestRoomsWithACLs(t *testing.T) {
|
|||
assert.Equal(t, []string{aclRoom.ID}, roomsWithACLs)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmptyRooms(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
alice := test.NewUser(t)
|
||||
r1 := test.NewRoom(t, alice)
|
||||
r2 := test.NewRoom(t, alice)
|
||||
|
||||
r2.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{"membership": spec.Leave}, test.WithStateKey(alice.ID))
|
||||
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
cfg, processCtx, closeDB := testrig.CreateConfig(t, dbType)
|
||||
defer closeDB()
|
||||
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
natsInstance := &jetstream.NATSInstance{}
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
// start JetStream listeners
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, natsInstance, caches, caching.DisableMetrics)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
|
||||
for _, room := range []*test.Room{r1, r2} {
|
||||
// Create the rooms
|
||||
err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
// We should only have r2 as an empty room
|
||||
emptyRooms, err := rsAPI.EmptyRooms(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []string{r2.ID}, emptyRooms)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,9 @@ type Database interface {
|
|||
|
||||
// RoomsWithACLs returns all room IDs for rooms with ACLs
|
||||
RoomsWithACLs(ctx context.Context) ([]string, error)
|
||||
|
||||
// EmptyRooms returns all rooms that the local server has left.
|
||||
EmptyRooms(ctx context.Context) ([]string, error)
|
||||
// GetBulkStateACLs returns all server ACLs for the given rooms.
|
||||
GetBulkStateACLs(ctx context.Context, roomIDs []string) ([]tables.StrippedEvent, error)
|
||||
QueryAdminEventReports(ctx context.Context, from uint64, limit uint64, backwards bool, userID string, roomID string) ([]api.QueryAdminEventReportsResponse, int64, error)
|
||||
|
|
|
|||
|
|
@ -1707,6 +1707,32 @@ func (d *Database) RoomsWithACLs(ctx context.Context) ([]string, error) {
|
|||
return roomIDs, nil
|
||||
}
|
||||
|
||||
// EmptyRooms returns all rooms that the local server has left.
|
||||
func (d *Database) EmptyRooms(ctx context.Context) ([]string, error) {
|
||||
eventTypeNID := types.EventTypeNID(5)
|
||||
|
||||
roomNIDs, err := d.EventsTable.SelectRoomsWithEventTypeNID(ctx, nil, eventTypeNID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Figure out if we are joined to the rooms
|
||||
leftRoomsNIDs := make([]types.RoomNID, 0, len(roomNIDs))
|
||||
for i := 0; i < len(roomNIDs); i++ {
|
||||
inRoom, err := d.GetLocalServerInRoom(ctx, roomNIDs[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if inRoom {
|
||||
continue
|
||||
}
|
||||
// Server is not in the room anymore
|
||||
leftRoomsNIDs = append(leftRoomsNIDs, roomNIDs[i])
|
||||
}
|
||||
|
||||
return d.RoomsTable.BulkSelectRoomIDs(ctx, nil, leftRoomsNIDs)
|
||||
}
|
||||
|
||||
// ForgetRoom sets a users room to forgotten
|
||||
func (d *Database) ForgetRoom(ctx context.Context, userID, roomID string, forget bool) error {
|
||||
roomNIDs, err := d.RoomsTable.BulkSelectRoomNIDs(ctx, nil, []string{roomID})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue