Merge 3670427da5 into 234acf0349
commit
d338ed8d0f
@ -0,0 +1,534 @@
|
||||
# MSC4375: Admin Room Management
|
||||
|
||||
*See also: [MSC4323: User suspension & locking endpoints][MSC4323]*
|
||||
|
||||
Every Matrix server supports rooms, big or small. What every server doesn't support, however, is the
|
||||
ability to manage the rooms that their server is participating in. Synapse has
|
||||
[the Synapse admin API][s1], Dendrite has [the Dendrite admin API][d1], Conduit and its derrivatives
|
||||
have [the admin room][c1], and other lesser known servers either have their own site-specific
|
||||
interfaces, or even none at all.
|
||||
|
||||
Such fragmentation in administration interfaces presents a great challenge to ecosystem developers
|
||||
who wish to provide room management capabilities to their users. Clients and moderation tools
|
||||
(which will be grouped together for this proposal) usually have to choose between supporting the
|
||||
Synapse admin API as it is the most deployed homeserver, guessing which implementation is in use and
|
||||
maintaining several implementation-specific calls, or just not supporting anything at all.
|
||||
|
||||
Translation layers, such as [conduwuit Admin API proxy][caap] (defunct) can be used to alleviate the
|
||||
problem at hand, however they simply shift the burden to another project, and introduce another
|
||||
moving part that has the potential to flake or fail. When it comes to moderation and administration,
|
||||
flakes and failures are generally not an acceptable risk, unless there is no other option.
|
||||
|
||||
This proposal is introducing some new client-to-server API endpoints that will allow the clients of
|
||||
priviliged users to have greater management capabilities over the homeserver.
|
||||
It will define interfaces to allow the listing of rooms the server has stored, fetching
|
||||
information regarding rooms, evacuating rooms (removing all local users), purging rooms, and
|
||||
blocking (to prevent future joins).
|
||||
|
||||
The reader is also encouraged to consider the usage of proposals such as
|
||||
[MSC4204: `m.takedown` moderation policy recommendation][MSC4204], which allows clients such as
|
||||
[Draupnir][draupnir] and [Meowlnir][meowlnir] to issue room "takedowns", which typically result in
|
||||
the client attempting to block, evacuate, and purge the room.
|
||||
|
||||
[MSC4323]: https://github.com/matrix-org/matrix-spec-proposals/pull/4323
|
||||
[s1]: https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html
|
||||
[d1]: https://element-hq.github.io/dendrite/administration/adminapi
|
||||
[c1]: https://continuwuity.org/admin_reference#admin-rooms-moderation
|
||||
[caap]: https://github.com/nexy7574/conduwuit-admin-api-proxy
|
||||
[MSC4204]: https://github.com/matrix-org/matrix-spec-proposals/pull/4204
|
||||
[draupnir]: https://github.com/the-draupnir-project/Draupnir
|
||||
[meowlnir]: https://github.com/maunium/meowlnir
|
||||
|
||||
## Proposal
|
||||
|
||||
> [!IMPORTANT]
|
||||
> [RFC2119](https://www.rfc-editor.org/rfc/rfc2119) is used here on out.
|
||||
>
|
||||
> What defines a "server administrator" is left up to the implementation itself as most already have
|
||||
> their own systems for defining administrators (e.g. Synapse has a database flag, Conduit has room
|
||||
> membership) which rarely has a reason to be exposed outside of their respective management
|
||||
> interfaces.
|
||||
>
|
||||
> All of the proposed endpoints are restricted to authenticated users, are not permitted
|
||||
> guest access, and MUST NOT be rate-limited.
|
||||
|
||||
Complementing [section 10.22 (Server Administration)][p1] of the client-to-server specification,
|
||||
eight new endpoints are introduced:
|
||||
|
||||
1. `GET /_matrix/client/v1/admin/rooms` - List rooms known to the homeserver
|
||||
2. `GET /_matrix/client/v1/admin/rooms/{roomID}` - Get room information (e.g. name, members, topic)
|
||||
3. `POST /_matrix/client/v1/admin/rooms/{roomID}/evacuate` - Start removing all local users from a room
|
||||
4. `GET /_matrix/client/v1/admin/rooms/{roomID}/evacuate/status` - Get room evacuation status
|
||||
5. `PUT /_matrix/client/v1/admin/rooms/{roomID}/blocked` - Block or unblock a room
|
||||
6. `DELETE /_matrix/client/v1/admin/rooms/{roomID}` - Start purging a room
|
||||
7. `GET /_matrix/cleint/v1/admin/rooms/{roomID}/delete/status` - Check the progress of a purge task
|
||||
8. `POST /_matrix/client/v1/admin/rooms/{roomID}/takeover` - Take over a room
|
||||
|
||||
[p1]: https://spec.matrix.org/v1.16/client-server-api/#server-administration
|
||||
|
||||
### List rooms
|
||||
|
||||
**`GET /_matrix/client/v1/admin/rooms`**
|
||||
|
||||
This endpoint allows the caller to iterate over the rooms known to the homeserver, allowing them to
|
||||
act upon the known room IDs (e.g. hash match, fetch information, purge, etc).
|
||||
|
||||
As homeservers might be aware of five or even six-digit room counts, this endpoint is restricted to
|
||||
returning only room IDs, expecting the client to fetch room data in follow-up for the rooms it may
|
||||
be interested in.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The endpoint has the following parameters:
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| `from` | string | Required | The end of the previous chunk (if any) |
|
||||
| `dir` | string (`f` or `b`) | Required | The direction to paginate (forward or backwards) |
|
||||
| `order_by` | string (see below) | `name` | The field to order the returned room IDs by |
|
||||
| `exclude_empty` | boolean | `false` | Exclude rooms with zero local members |
|
||||
| `exclude_private` | boolean | `false` | Exclude rooms with a join rule other than `public` |
|
||||
| `exclude_public` | boolean | `false` | Exclude rooms with a join rule of `public` |
|
||||
| `exclude_encrypted` | boolean | `false` | Exclude encrypted rooms |
|
||||
| `exclude_unencrypted` | boolean | `false` | Exclude unencrypted rooms |
|
||||
| `exclude_federated` | boolean | `false` | Exclude rooms where `m.federate` is missing or `true` |
|
||||
| `exclude_unfederated` | boolean | `false` | Exclude rooms where `m.federate` is `false` |
|
||||
| `only_origins` | [glob[]][spec-glob] | `["*"]` | Only include rooms where any of the provided globs match the `m.room.create` `sender` |
|
||||
|
||||
**Order by** can be any of the following:
|
||||
- `name`: Sort by room name in [lexographical order](https://en.wikipedia.org/wiki/Lexicographic_order).
|
||||
Rooms with no `m.room.name` event are considered to have an empty string for a room name.
|
||||
- `local_members`: Sort by local member count in descending order (largest -> smallest).
|
||||
- `total_members`: Sort by total member count in descending order (largest -> smallest).
|
||||
- `created_at`: Sort by the room creation timestamp (newest -> oldest).
|
||||
- `room_version`: Sort by the room version (oldest -> newest). Unstable room versions are treated as
|
||||
"newest", and sorted lexographically.
|
||||
- `latest_event`: Sort by the timestamp of the latest received event (oldest -> newest). Events that
|
||||
soft-failed SHOULD be considered in the sorting.
|
||||
|
||||
Servers MUST NOT allow `limit` to be greater than 500, and MUST wrap the provided `limit` to the cap
|
||||
if it exceeds it.
|
||||
|
||||
`order_by` MUST be case insensitive and servers MUST ignore any unknown values.
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The sever successfully processed the request.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"end": "...", // a pagination token represending the end of the chunk, if any.
|
||||
"chunk": ["!room1", "!room2", "..."], // an array of room IDs the server knows about
|
||||
}
|
||||
```
|
||||
|
||||
Clients MUST stop paginating once they encounter a response with an empty or missing `end`, as this
|
||||
indicates there are no more rooms.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. mismatched type).
|
||||
|
||||
**403 `M_FORBIDDEN`**: The user does not have permission to list homeserver rooms.
|
||||
|
||||
### Get room information
|
||||
|
||||
**`GET /_matrix/client/v1/admin/rooms/{roomID}`**
|
||||
|
||||
In order to provide clients with a general overview of a room without joining, even if it is
|
||||
a non-public room, a limited subset of the room state is provided to clients. This allows them to
|
||||
fetch vital information, such as who created the room, the name/avatar/topic of the room, its join
|
||||
rules, guest access, canonical alias(es), and history visibility. This information can be used
|
||||
(for example) to render the room to a user, and potentially to determine an abuse risk value.
|
||||
|
||||
The `m.room.create` event **MUST** be returned.
|
||||
|
||||
The following state events SHOULD be returned, if present:
|
||||
|
||||
- `m.room.name`
|
||||
- `m.room.avatar`
|
||||
- `m.room.join_rules`
|
||||
- `m.room.power_levels`
|
||||
- `m.room.guest_access`
|
||||
- `m.room.history_visibility`
|
||||
- `m.room.canonical_alias`
|
||||
- `m.room.topic`
|
||||
|
||||
The following state events MAY be returned, if present:
|
||||
|
||||
- `m.room.server_acl`
|
||||
- `m.space.parent` (all keys)
|
||||
- `m.room.pinned_events`
|
||||
|
||||
`m.room.member` events MUST NOT be present UNLESS `include_members` is true.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
This endpoint has the following query parameters:
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| `include_members` | boolean | `false` | Include **all** room membership events |
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server successfully fetched the information requested.
|
||||
|
||||
State events should be fully formatted client events, not stripped.
|
||||
|
||||
```json
|
||||
{
|
||||
"state": [
|
||||
{
|
||||
"type": "...",
|
||||
"sender": "...",
|
||||
"content": "...",
|
||||
"state_key": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**400 `M_INVALID_PARAM`**: `include_members` was not a valid boolean, or the `roomID` was malformed.
|
||||
|
||||
**403 `M_FORIDDEN`**: The user does not have permission to fetch room information as they are not an
|
||||
administrator.
|
||||
|
||||
**404 `M_NOT_FOUND`**: The room provided is not known to the server
|
||||
|
||||
### Start room evacuation
|
||||
|
||||
**`POST /_matrix/client/v1/admin/rooms/{roomID}/evacuate`**
|
||||
|
||||
This endpoint exposes a method to allow clients to "evacuate" rooms. Evacuating rooms is usually a
|
||||
step taken before purging or blocking them, to ensure that local users are no longer participating
|
||||
in a room as ghosts when further action is taken.
|
||||
|
||||
Evacuate also has the capability to replace a room with a new one, to inform users that they were
|
||||
evacuated.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This endpoint is expected to potentially take a long time to process, so an "asynchronous"
|
||||
> approach is taken. Implementations SHOULD fork off the task into a background process, immediately
|
||||
> returning to the client, however MAY block the request until the evacuation is complete.
|
||||
>
|
||||
> As specified below, clients may specify a preference for this behaviour.
|
||||
|
||||
Servers MUST NOT permit concurrent evacuations on the same room ID.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Request Body
|
||||
|
||||
The request body for this endpoint is shaped like the following:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Don't abort the evacuation if removing a member fails or there is some other non-fatal error.
|
||||
"force": false,
|
||||
// If false, request that the server doesn't cast the task to the background, instead blocking
|
||||
// the request until the evacuation completes.
|
||||
// If true, request that the server casts the evacuation into a background task as soon as
|
||||
// possible.
|
||||
// If omitted, the server chooses what happens.
|
||||
"background": true,
|
||||
|
||||
// Details for creating a replacement room that all evacuated members will be joined to.
|
||||
// If omitted, no new room is created.
|
||||
"replace_with": {
|
||||
// The user ID who will create this room. Defaults to the calling user if omitted.
|
||||
"creator": "@abuse:example.org",
|
||||
// The initial state for this new room. The same as /createRoom.
|
||||
"initial_state": [
|
||||
{ // e.g.
|
||||
"type": "m.room.name",
|
||||
"state_key": "",
|
||||
"content": {
|
||||
"name": "Content Violation Notice"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Clients SHOULD allow for a large timeout on requests to this endpoint, especially if they set
|
||||
`"background": false`. This may not be possible in externally-controlled environments, such as in
|
||||
the browser.
|
||||
|
||||
Servers MAY ignore the `background` preference, if specified.
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server processed the request successfully.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Boolean indicating if the evacuation is carrying on in the background.
|
||||
"background": true,
|
||||
// The number of members removed from the room, if any. Can be omitted when background processing.
|
||||
// Must be a non-negative integer if provided.
|
||||
"removed": 0
|
||||
}
|
||||
```
|
||||
|
||||
**400 `M_BAD_JSON`**: `force` or `background` were not booleans.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. room ID is malformed).
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to evacuate rooms.
|
||||
|
||||
**429 `M_LIMIT_EXCEEDED`**: An evacuation for this room is already in progress, try again later.
|
||||
|
||||
Unlike other endpoints, `M_NOT_FOUND` MUST NOT be returned. Evacuating an unknown room should always
|
||||
return `200 OK` with `background: false` and `removed: 0`.
|
||||
|
||||
### Get room evacuation status
|
||||
|
||||
**`GET /_matrix/client/v1/admin/rooms/{roomID}/evacuate/status`**
|
||||
|
||||
This endpoint allows clients to check on the status of a room evacuation task.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server is processing an evacuation and returned the following information:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Unix milliseconds indicating the time at which this evacuation started.
|
||||
"started_at": 123456789,
|
||||
// The total number of users that need to be evacuated
|
||||
"total": 0,
|
||||
// The number of users that have been evacuated so far (excluding failed)
|
||||
"evacuated": 0,
|
||||
// The number of users that could not be evacuated so far.
|
||||
"failed": 0
|
||||
}
|
||||
```
|
||||
|
||||
The server MAY omit keys whose value is zero.
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to evacuate rooms.
|
||||
|
||||
**404 `M_NOT_FOUND`**: There is no ongoing evacuation task for this room.
|
||||
|
||||
### Block or unblock a room
|
||||
|
||||
**`PUT /_matrix/client/v1/admin/rooms/{roomID}/blocked`**
|
||||
|
||||
This endpoint blocks or unblocks a room. Blocked rooms cannot be joined by future local members.
|
||||
Servers SHOULD NOT require that the room has been evacuated before being blocked, as preventing
|
||||
future joins may be more critical than ensuring that there are no ghosts, and evacuations may take
|
||||
a long time.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Request Body
|
||||
|
||||
The request body for this endpoint is shaped like the following:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"blocked": true // or false
|
||||
}
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The room was blocked or unblocked. An empty response (`{}`) is returned.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. room ID is malformed).
|
||||
|
||||
**400 `M_BAD_JSON`**: The value of `blocked` is neither `true` nor `false`.
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to un/block rooms.
|
||||
|
||||
|
||||
### Start room purge
|
||||
|
||||
**`DELETE /_matrix/client/v1/admin/rooms/{roomID}`**
|
||||
|
||||
This endpoint exposes a method to allow clients to "purge" rooms. "Purging" a room is left as an
|
||||
implementation-specific, but generally involves deleting as much of the stored data associated with
|
||||
the room as possible, such as stored events and memberships.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This endpoint is expected to potentially take a long time to process, so an "asynchronous"
|
||||
> approach is taken. Implementations SHOULD fork off the task into a background process, immediately
|
||||
> returning to the client, however MAY block the request until the purge is complete.
|
||||
>
|
||||
> As specified below, clients may specify a preference for this behaviour.
|
||||
|
||||
Servers MUST NOT permit concurrent purges on the same room ID.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Request Body
|
||||
|
||||
The request body for this endpoint is shaped like the following:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Ignore any local restrictions (such as requiring a room be evacuated) and any non-fatal errors
|
||||
"force": false,
|
||||
// If false, request that the server doesn't cast the task to the background, instead blocking
|
||||
// the request until the purge completes.
|
||||
// If true, request that the server casts the purge into a background task as soon as possible.
|
||||
// If omitted, the server chooses what happens.
|
||||
"background": true
|
||||
}
|
||||
```
|
||||
|
||||
Clients SHOULD allow for a large timeout on requests to this endpoint, especially if they set
|
||||
`"background": false`. This may not be possible in externally-controlled environments, such as in
|
||||
the browser.
|
||||
|
||||
Servers MAY ignore the `background` preference, if specified.
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server processed the request successfully.
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Boolean indicating if the purge is carrying on in the background.
|
||||
"background": true
|
||||
}
|
||||
```
|
||||
|
||||
**400 `M_BAD_JSON`**: `force` or `background` were not booleans.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. room ID is malformed).
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to purge rooms.
|
||||
|
||||
**429 `M_LIMIT_EXCEEDED`**: A purge for this room is already in progress, try again later.
|
||||
|
||||
Unlike other endpoints, `M_NOT_FOUND` MUST NOT be returned. Purging an unknown room should always
|
||||
return `200 OK` with `background: false`.
|
||||
|
||||
### Get room purge status
|
||||
|
||||
**`GET /_matrix/client/v1/admin/rooms/{roomID}/delete/status`**
|
||||
|
||||
This endpoint allows clients to check on the status of a room purge task.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server is processing a purge and returned the following information:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// Unix milliseconds indicating the time at which this purge started.
|
||||
"started_at": 123456789
|
||||
}
|
||||
```
|
||||
|
||||
The server MAY omit keys whose value is zero.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. room ID is malformed).
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to evacuate rooms.
|
||||
|
||||
**404 `M_NOT_FOUND`**: There is no ongoing purge task for this room.
|
||||
|
||||
### Take over room
|
||||
|
||||
**`POST /_matrix/client/v1/admin/rooms/{roomID}/takeover`**
|
||||
|
||||
This endpoint allows the calling user to "take over" the room by puppeting a local user in the room
|
||||
that is able to escalate the caller's power level. This typically means finding local users that can
|
||||
send `m.room.power_level` state events, sorting for the one with the higest power level, and
|
||||
sending a new power level event with the calling user at the same power level as the puppetted user.
|
||||
|
||||
If the calling user is not in the room, servers SHOULD take similar steps to puppet a local user
|
||||
into producing an invite for the calling user. This ensures that the user is able to join and use
|
||||
their new power level regardless of room access restrictions. This may also involve unbanning the
|
||||
calling user, if they were previously banned.
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
The request has the `roomID` path param which must be a fully qualified room ID (i.e. a string
|
||||
starting with the `!` sigil).
|
||||
|
||||
#### Request Body
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// The user ID to give the new power level to. Defaults to the authenticated user.
|
||||
// MUST be local to the current homeserver.
|
||||
"user_id": "@admin:example.com"
|
||||
}
|
||||
```
|
||||
|
||||
#### Response
|
||||
|
||||
**200 OK**: The server successfully updated the power levels and optionally invited the caller.
|
||||
An empty response (`{}`) is returned.
|
||||
|
||||
**400 `M_INVALID_PARAM`**: The request is not well formed (e.g. room ID is malformed).
|
||||
|
||||
**400 `M_FORBIDDEN`**: The server was unable to take over the room, usually due to a lack of
|
||||
privileged local users.
|
||||
|
||||
**403 `M_FORBIDDEN`**: The requesting user does not have permission to evacuate rooms.
|
||||
|
||||
**404 `M_NOT_FOUND`**: The room is not known to the server
|
||||
|
||||
## Potential issues
|
||||
|
||||
TODO
|
||||
|
||||
## Alternatives
|
||||
|
||||
Aside from the status quo, none are known at this time.
|
||||
|
||||
## Security considerations
|
||||
|
||||
Rooms are the lifeblood of Matrix, so this proposal introduces some incredibly powerful endpoints.
|
||||
Misuse of the powers granted can result in permanent data loss (namely in the event of local-only
|
||||
rooms being purged) and potentially irreversible privilage escalation via takeovers.
|
||||
|
||||
This propsal assumes the server is secure and administrator rights are only granted to trustworthy
|
||||
people. There is inherently no way to defend against such malicious usage that remains in-scope of
|
||||
this proposal.
|
||||
|
||||
## Unstable prefix
|
||||
|
||||
| Stable | Unstable |
|
||||
| `/_matrix/client/v1/` | `/_matrix/client/unstable/uk.timedout.msc4375/` |
|
||||
|
||||
Servers SHOULD advertise support for this functionality via `/_matrix/client/versions`,
|
||||
OPTIONALLY only to authenticated users.
|
||||
Servers MUST NOT advertise support UNLESS they support AT LEAST the following endpoints:
|
||||
|
||||
- `GET /_matrix/client/v1/admin/rooms`
|
||||
- `GET /_matrix/client/v1/admin/rooms/{roomID}`
|
||||
- `POST /_matrix/client/v1/admin/rooms/{roomID}/evacuate`
|
||||
- If `GET /_matrix/client/v1/admin/rooms/{roomID}/evacuate/status` is not supported, `background`
|
||||
must always be `false`.
|
||||
- `PUT /_matrix/client/v1/admin/rooms/{roomID}/blocked`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None
|
||||
Loading…
Reference in New Issue