Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Remove deprecated delete room admin API POST /_synapse/admin/v1/rooms/<room_id>/delete #11213

Merged
merged 6 commits into from Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/11213.removal
@@ -0,0 +1 @@
Remove deprecated admin API to delete rooms (`POST /_synapse/admin/v1/rooms/<room_id>/delete`).
10 changes: 0 additions & 10 deletions docs/admin_api/rooms.md
Expand Up @@ -520,16 +520,6 @@ With all that being said, if you still want to try and recover the room:
4. If `new_room_user_id` was given, a 'Content Violation' will have been
created. Consider whether you want to delete that roomm.

## Deprecated endpoint

The previous deprecated API will be removed in a future release, it was:

```
POST /_synapse/admin/v1/rooms/<room_id>/delete
```

It behaves the same way than the current endpoint except the path and the method.

# Make Room Admin API

Grants another user the highest power available to a local user who is in the room.
Expand Down
10 changes: 10 additions & 0 deletions docs/upgrade.md
Expand Up @@ -87,6 +87,16 @@ process, for example:

# Upgrading to v1.47.0

## Removal of old Room Admin API

The following admin APIs were deprecated in [Synapse 1.34](https://github.com/matrix-org/synapse/blob/v1.34.0/CHANGES.md#deprecations-and-removals)
(released on 2021-05-17) and have now been removed:

- `POST /_synapse/admin/v1/<room_id>/delete`

Any scripts still using the above APIs should be converted to use the
[Delete Room API](https://matrix-org.github.io/synapse/latest/admin_api/rooms.html#delete-room-api).

## Deprecation of the `user_may_create_room_with_invites` module callback

The `user_may_create_room_with_invites` is deprecated and will be removed in a future
Expand Down
2 changes: 0 additions & 2 deletions synapse/rest/admin/__init__.py
Expand Up @@ -42,7 +42,6 @@
RegistrationTokenRestServlet,
)
from synapse.rest.admin.rooms import (
DeleteRoomRestServlet,
ForwardExtremitiesRestServlet,
JoinRoomAliasServlet,
ListRoomRestServlet,
Expand Down Expand Up @@ -221,7 +220,6 @@ def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
RoomStateRestServlet(hs).register(http_server)
RoomRestServlet(hs).register(http_server)
RoomMembersRestServlet(hs).register(http_server)
DeleteRoomRestServlet(hs).register(http_server)
JoinRoomAliasServlet(hs).register(http_server)
VersionServlet(hs).register(http_server)
UserAdminServlet(hs).register(http_server)
Expand Down
141 changes: 53 additions & 88 deletions synapse/rest/admin/rooms.py
Expand Up @@ -46,41 +46,6 @@
logger = logging.getLogger(__name__)


class DeleteRoomRestServlet(RestServlet):
"""Delete a room from server.

It is a combination and improvement of shutdown and purge room.

Shuts down a room by removing all local users from the room.
Blocking all future invites and joins to the room is optional.

If desired any local aliases will be repointed to a new room
created by `new_room_user_id` and kicked users will be auto-
joined to the new room.

If 'purge' is true, it will remove all traces of a room from the database.
"""

PATTERNS = admin_patterns("/rooms/(?P<room_id>[^/]+)/delete$")

def __init__(self, hs: "HomeServer"):
self.hs = hs
self.auth = hs.get_auth()
self.room_shutdown_handler = hs.get_room_shutdown_handler()
self.pagination_handler = hs.get_pagination_handler()

async def on_POST(
self, request: SynapseRequest, room_id: str
) -> Tuple[int, JsonDict]:
return await _delete_room(
request,
room_id,
self.auth,
self.room_shutdown_handler,
self.pagination_handler,
)


class ListRoomRestServlet(RestServlet):
"""
List all rooms that are known to the homeserver. Results are returned
Expand Down Expand Up @@ -218,14 +183,66 @@ async def on_GET(
async def on_DELETE(
self, request: SynapseRequest, room_id: str
) -> Tuple[int, JsonDict]:
return await _delete_room(
return await self._delete_room(
request,
room_id,
self.auth,
self.room_shutdown_handler,
self.pagination_handler,
)

async def _delete_room(
self,
request: SynapseRequest,
room_id: str,
auth: "Auth",
room_shutdown_handler: "RoomShutdownHandler",
pagination_handler: "PaginationHandler",
) -> Tuple[int, JsonDict]:
requester = await auth.get_user_by_req(request)
await assert_user_is_admin(auth, requester.user)

content = parse_json_object_from_request(request)

block = content.get("block", False)
if not isinstance(block, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'block' must be a boolean, if given",
Codes.BAD_JSON,
)

purge = content.get("purge", True)
if not isinstance(purge, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'purge' must be a boolean, if given",
Codes.BAD_JSON,
)

force_purge = content.get("force_purge", False)
if not isinstance(force_purge, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'force_purge' must be a boolean, if given",
Codes.BAD_JSON,
)

ret = await room_shutdown_handler.shutdown_room(
room_id=room_id,
new_room_user_id=content.get("new_room_user_id"),
new_room_name=content.get("room_name"),
message=content.get("message"),
requester_user_id=requester.user.to_string(),
block=block,
)

# Purge room
if purge:
await pagination_handler.purge_room(room_id, force=force_purge)

return 200, ret


class RoomMembersRestServlet(RestServlet):
"""
Expand Down Expand Up @@ -617,55 +634,3 @@ async def on_GET(
)

return 200, results


async def _delete_room(
request: SynapseRequest,
room_id: str,
auth: "Auth",
room_shutdown_handler: "RoomShutdownHandler",
pagination_handler: "PaginationHandler",
) -> Tuple[int, JsonDict]:
requester = await auth.get_user_by_req(request)
await assert_user_is_admin(auth, requester.user)

content = parse_json_object_from_request(request)

block = content.get("block", False)
if not isinstance(block, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'block' must be a boolean, if given",
Codes.BAD_JSON,
)

purge = content.get("purge", True)
if not isinstance(purge, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'purge' must be a boolean, if given",
Codes.BAD_JSON,
)

force_purge = content.get("force_purge", False)
if not isinstance(force_purge, bool):
raise SynapseError(
HTTPStatus.BAD_REQUEST,
"Param 'force_purge' must be a boolean, if given",
Codes.BAD_JSON,
)

ret = await room_shutdown_handler.shutdown_room(
room_id=room_id,
new_room_user_id=content.get("new_room_user_id"),
new_room_name=content.get("room_name"),
message=content.get("message"),
requester_user_id=requester.user.to_string(),
block=block,
)

# Purge room
if purge:
await pagination_handler.purge_room(room_id, force=force_purge)

return 200, ret
39 changes: 15 additions & 24 deletions tests/rest/admin/test_room.py
Expand Up @@ -17,8 +17,6 @@
from typing import List, Optional
from unittest.mock import Mock

from parameterized import parameterized_class

import synapse.rest.admin
from synapse.api.constants import EventTypes, Membership
from synapse.api.errors import Codes
Expand All @@ -29,13 +27,6 @@
"""Tests admin REST events for /rooms paths."""


@parameterized_class(
("method", "url_template"),
[
("POST", "/_synapse/admin/v1/rooms/%s/delete"),
("DELETE", "/_synapse/admin/v1/rooms/%s"),
],
)
class DeleteRoomTestCase(unittest.HomeserverTestCase):
servlets = [
synapse.rest.admin.register_servlets,
Expand Down Expand Up @@ -67,15 +58,15 @@ def prepare(self, reactor, clock, hs):
self.room_id = self.helper.create_room_as(
self.other_user, tok=self.other_user_tok
)
self.url = self.url_template % self.room_id
self.url = "/_synapse/admin/v1/rooms/%s" % self.room_id

def test_requester_is_no_admin(self):
"""
If the user is not a server admin, an error 403 is returned.
"""

channel = self.make_request(
self.method,
"DELETE",
self.url,
json.dumps({}),
access_token=self.other_user_tok,
Expand All @@ -88,10 +79,10 @@ def test_room_does_not_exist(self):
"""
Check that unknown rooms/server return error 404.
"""
url = self.url_template % "!unknown:test"
url = "/_synapse/admin/v1/rooms/%s" % "!unknown:test"

channel = self.make_request(
self.method,
"DELETE",
url,
json.dumps({}),
access_token=self.admin_user_tok,
Expand All @@ -104,10 +95,10 @@ def test_room_is_not_valid(self):
"""
Check that invalid room names, return an error 400.
"""
url = self.url_template % "invalidroom"
url = "/_synapse/admin/v1/rooms/%s" % "invalidroom"

channel = self.make_request(
self.method,
"DELETE",
url,
json.dumps({}),
access_token=self.admin_user_tok,
Expand All @@ -126,7 +117,7 @@ def test_new_room_user_does_not_exist(self):
body = json.dumps({"new_room_user_id": "@unknown:test"})

channel = self.make_request(
self.method,
"DELETE",
self.url,
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand All @@ -145,7 +136,7 @@ def test_new_room_user_is_not_local(self):
body = json.dumps({"new_room_user_id": "@not:exist.bla"})

channel = self.make_request(
self.method,
"DELETE",
self.url,
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand All @@ -164,7 +155,7 @@ def test_block_is_not_bool(self):
body = json.dumps({"block": "NotBool"})

channel = self.make_request(
self.method,
"DELETE",
self.url,
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand All @@ -180,7 +171,7 @@ def test_purge_is_not_bool(self):
body = json.dumps({"purge": "NotBool"})

channel = self.make_request(
self.method,
"DELETE",
self.url,
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand All @@ -206,7 +197,7 @@ def test_purge_room_and_block(self):
body = json.dumps({"block": True, "purge": True})

channel = self.make_request(
self.method,
"DELETE",
self.url.encode("ascii"),
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand Down Expand Up @@ -239,7 +230,7 @@ def test_purge_room_and_not_block(self):
body = json.dumps({"block": False, "purge": True})

channel = self.make_request(
self.method,
"DELETE",
self.url.encode("ascii"),
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand Down Expand Up @@ -273,7 +264,7 @@ def test_block_room_and_not_purge(self):
body = json.dumps({"block": False, "purge": False})

channel = self.make_request(
self.method,
"DELETE",
self.url.encode("ascii"),
content=body.encode(encoding="utf_8"),
access_token=self.admin_user_tok,
Expand Down Expand Up @@ -319,7 +310,7 @@ def test_shutdown_room_consent(self):

# Test that the admin can still send shutdown
channel = self.make_request(
self.method,
"DELETE",
self.url,
json.dumps({"new_room_user_id": self.admin_user}),
access_token=self.admin_user_tok,
Expand Down Expand Up @@ -365,7 +356,7 @@ def test_shutdown_room_block_peek(self):

# Test that the admin can still send shutdown
channel = self.make_request(
self.method,
"DELETE",
self.url,
json.dumps({"new_room_user_id": self.admin_user}),
access_token=self.admin_user_tok,
Expand Down