mirror of
https://github.com/element-hq/synapse
synced 2024-09-29 14:42:42 +00:00
Merge branch 'develop' into madlittlemods/msc3575-sliding-sync-filter-dms
This commit is contained in:
commit
9896478297
17 changed files with 274 additions and 30 deletions
2
.github/workflows/docs-pr-netlify.yaml
vendored
2
.github/workflows/docs-pr-netlify.yaml
vendored
|
@ -14,7 +14,7 @@ jobs:
|
||||||
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
|
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
|
||||||
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
|
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
|
||||||
- name: 📥 Download artifact
|
- name: 📥 Download artifact
|
||||||
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
|
uses: dawidd6/action-download-artifact@deb3bb83256a78589fef6a7b942e5f2573ad7c13 # v5
|
||||||
with:
|
with:
|
||||||
workflow: docs-pr.yaml
|
workflow: docs-pr.yaml
|
||||||
run_id: ${{ github.event.workflow_run.id }}
|
run_id: ${{ github.event.workflow_run.id }}
|
||||||
|
|
10
CHANGES.md
10
CHANGES.md
|
@ -1,3 +1,13 @@
|
||||||
|
# Synapse 1.109.0rc2 (2024-06-11)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Fix bug where one-time-keys were not always included in `/sync` response when using workers. Introduced in v1.109.0rc1. ([\#17275](https://github.com/element-hq/synapse/issues/17275))
|
||||||
|
- Fix bug where `/sync` could get stuck due to edge case in device lists handling. Introduced in v1.109.0rc1. ([\#17292](https://github.com/element-hq/synapse/issues/17292))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Synapse 1.109.0rc1 (2024-06-04)
|
# Synapse 1.109.0rc1 (2024-06-04)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -444,9 +444,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
1
changelog.d/17270.feature
Normal file
1
changelog.d/17270.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add support for the unstable [MSC4151](https://github.com/matrix-org/matrix-spec-proposals/pull/4151) report room API.
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
matrix-synapse-py3 (1.109.0~rc2) stable; urgency=medium
|
||||||
|
|
||||||
|
* New synapse release 1.109.0rc2.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 11 Jun 2024 13:20:17 +0000
|
||||||
|
|
||||||
matrix-synapse-py3 (1.109.0~rc1) stable; urgency=medium
|
matrix-synapse-py3 (1.109.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
* New Synapse release 1.109.0rc1.
|
* New Synapse release 1.109.0rc1.
|
||||||
|
|
18
poetry.lock
generated
18
poetry.lock
generated
|
@ -912,13 +912,13 @@ trio = ["async_generator", "trio"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jinja2"
|
name = "jinja2"
|
||||||
version = "3.1.3"
|
version = "3.1.4"
|
||||||
description = "A very fast and expressive template engine."
|
description = "A very fast and expressive template engine."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
|
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
|
||||||
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
|
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2808,13 +2808,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-jsonschema"
|
name = "types-jsonschema"
|
||||||
version = "4.21.0.20240311"
|
version = "4.22.0.20240610"
|
||||||
description = "Typing stubs for jsonschema"
|
description = "Typing stubs for jsonschema"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "types-jsonschema-4.21.0.20240311.tar.gz", hash = "sha256:f7165ce70abd91df490c73b089873afd2899c5e56430ee495b64f851ad01f287"},
|
{file = "types-jsonschema-4.22.0.20240610.tar.gz", hash = "sha256:f82ab9fe756e3a2642ea9712c46b403ce61eb380b939b696cff3252af42f65b0"},
|
||||||
{file = "types_jsonschema-4.21.0.20240311-py3-none-any.whl", hash = "sha256:e872f5661513824edf9698f73a66c9c114713d93eab58699bd0532e7e6db5750"},
|
{file = "types_jsonschema-4.22.0.20240610-py3-none-any.whl", hash = "sha256:89996b9bd1928f820a0e252b2844be21cd2e55d062b6fa1048d88453006ad89e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2844,13 +2844,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-pillow"
|
name = "types-pillow"
|
||||||
version = "10.2.0.20240423"
|
version = "10.2.0.20240520"
|
||||||
description = "Typing stubs for Pillow"
|
description = "Typing stubs for Pillow"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "types-Pillow-10.2.0.20240423.tar.gz", hash = "sha256:696e68b9b6a58548fc307a8669830469237c5b11809ddf978ac77fafa79251cd"},
|
{file = "types-Pillow-10.2.0.20240520.tar.gz", hash = "sha256:130b979195465fa1e1676d8e81c9c7c30319e8e95b12fae945e8f0d525213107"},
|
||||||
{file = "types_Pillow-10.2.0.20240423-py3-none-any.whl", hash = "sha256:bd12923093b96c91d523efcdb66967a307f1a843bcfaf2d5a529146c10a9ced3"},
|
{file = "types_Pillow-10.2.0.20240520-py3-none-any.whl", hash = "sha256:33c36494b380e2a269bb742181bea5d9b00820367822dbd3760f07210a1da23d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -96,7 +96,7 @@ module-name = "synapse.synapse_rust"
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "matrix-synapse"
|
name = "matrix-synapse"
|
||||||
version = "1.109.0rc1"
|
version = "1.109.0rc2"
|
||||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||||
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
|
|
|
@ -443,3 +443,6 @@ class ExperimentalConfig(Config):
|
||||||
self.msc3916_authenticated_media_enabled = experimental.get(
|
self.msc3916_authenticated_media_enabled = experimental.get(
|
||||||
"msc3916_authenticated_media_enabled", False
|
"msc3916_authenticated_media_enabled", False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# MSC4151: Report room API (Client-Server API)
|
||||||
|
self.msc4151_enabled: bool = experimental.get("msc4151_enabled", False)
|
||||||
|
|
|
@ -53,7 +53,7 @@ from synapse.rest.client import (
|
||||||
register,
|
register,
|
||||||
relations,
|
relations,
|
||||||
rendezvous,
|
rendezvous,
|
||||||
report_event,
|
reporting,
|
||||||
room,
|
room,
|
||||||
room_keys,
|
room_keys,
|
||||||
room_upgrade_rest_servlet,
|
room_upgrade_rest_servlet,
|
||||||
|
@ -128,7 +128,7 @@ class ClientRestResource(JsonResource):
|
||||||
tags.register_servlets(hs, client_resource)
|
tags.register_servlets(hs, client_resource)
|
||||||
account_data.register_servlets(hs, client_resource)
|
account_data.register_servlets(hs, client_resource)
|
||||||
if is_main_process:
|
if is_main_process:
|
||||||
report_event.register_servlets(hs, client_resource)
|
reporting.register_servlets(hs, client_resource)
|
||||||
openid.register_servlets(hs, client_resource)
|
openid.register_servlets(hs, client_resource)
|
||||||
notifications.register_servlets(hs, client_resource)
|
notifications.register_servlets(hs, client_resource)
|
||||||
devices.register_servlets(hs, client_resource)
|
devices.register_servlets(hs, client_resource)
|
||||||
|
|
|
@ -23,17 +23,28 @@ import logging
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import TYPE_CHECKING, Tuple
|
from typing import TYPE_CHECKING, Tuple
|
||||||
|
|
||||||
|
from synapse._pydantic_compat import HAS_PYDANTIC_V2
|
||||||
from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
|
from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
|
||||||
from synapse.http.server import HttpServer
|
from synapse.http.server import HttpServer
|
||||||
from synapse.http.servlet import RestServlet, parse_json_object_from_request
|
from synapse.http.servlet import (
|
||||||
|
RestServlet,
|
||||||
|
parse_and_validate_json_object_from_request,
|
||||||
|
parse_json_object_from_request,
|
||||||
|
)
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
|
from synapse.types.rest import RequestBodyModel
|
||||||
|
|
||||||
from ._base import client_patterns
|
from ._base import client_patterns
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
|
if TYPE_CHECKING or HAS_PYDANTIC_V2:
|
||||||
|
from pydantic.v1 import StrictStr
|
||||||
|
else:
|
||||||
|
from pydantic import StrictStr
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,5 +106,49 @@ class ReportEventRestServlet(RestServlet):
|
||||||
return 200, {}
|
return 200, {}
|
||||||
|
|
||||||
|
|
||||||
|
class ReportRoomRestServlet(RestServlet):
|
||||||
|
# https://github.com/matrix-org/matrix-spec-proposals/pull/4151
|
||||||
|
PATTERNS = client_patterns(
|
||||||
|
"/org.matrix.msc4151/rooms/(?P<room_id>[^/]*)/report$",
|
||||||
|
releases=[],
|
||||||
|
v1=False,
|
||||||
|
unstable=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, hs: "HomeServer"):
|
||||||
|
super().__init__()
|
||||||
|
self.hs = hs
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
self.clock = hs.get_clock()
|
||||||
|
self.store = hs.get_datastores().main
|
||||||
|
|
||||||
|
class PostBody(RequestBodyModel):
|
||||||
|
reason: StrictStr
|
||||||
|
|
||||||
|
async def on_POST(
|
||||||
|
self, request: SynapseRequest, room_id: str
|
||||||
|
) -> Tuple[int, JsonDict]:
|
||||||
|
requester = await self.auth.get_user_by_req(request)
|
||||||
|
user_id = requester.user.to_string()
|
||||||
|
|
||||||
|
body = parse_and_validate_json_object_from_request(request, self.PostBody)
|
||||||
|
|
||||||
|
room = await self.store.get_room(room_id)
|
||||||
|
if room is None:
|
||||||
|
raise NotFoundError("Room does not exist")
|
||||||
|
|
||||||
|
await self.store.add_room_report(
|
||||||
|
room_id=room_id,
|
||||||
|
user_id=user_id,
|
||||||
|
reason=body.reason,
|
||||||
|
received_ts=self.clock.time_msec(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return 200, {}
|
||||||
|
|
||||||
|
|
||||||
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
|
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
|
||||||
ReportEventRestServlet(hs).register(http_server)
|
ReportEventRestServlet(hs).register(http_server)
|
||||||
|
|
||||||
|
if hs.config.experimental.msc4151_enabled:
|
||||||
|
ReportRoomRestServlet(hs).register(http_server)
|
|
@ -149,6 +149,8 @@ class VersionsRestServlet(RestServlet):
|
||||||
is not None
|
is not None
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
# MSC4151: Report room API (Client-Server API)
|
||||||
|
"org.matrix.msc4151": self.config.experimental.msc4151_enabled,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -108,6 +108,11 @@ class DeviceWorkerStore(RoomMemberWorkerStore, EndToEndKeyWorkerStore):
|
||||||
("device_lists_outbound_pokes", "instance_name", "stream_id"),
|
("device_lists_outbound_pokes", "instance_name", "stream_id"),
|
||||||
("device_lists_changes_in_room", "instance_name", "stream_id"),
|
("device_lists_changes_in_room", "instance_name", "stream_id"),
|
||||||
("device_lists_remote_pending", "instance_name", "stream_id"),
|
("device_lists_remote_pending", "instance_name", "stream_id"),
|
||||||
|
(
|
||||||
|
"device_lists_changes_converted_stream_position",
|
||||||
|
"instance_name",
|
||||||
|
"stream_id",
|
||||||
|
),
|
||||||
],
|
],
|
||||||
sequence_name="device_lists_sequence",
|
sequence_name="device_lists_sequence",
|
||||||
writers=["master"],
|
writers=["master"],
|
||||||
|
@ -2394,15 +2399,16 @@ class DeviceStore(DeviceWorkerStore, DeviceBackgroundUpdateStore):
|
||||||
`FALSE` have not been converted.
|
`FALSE` have not been converted.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return cast(
|
# There should be only one row in this table, though we want to
|
||||||
Tuple[int, str],
|
# future-proof ourselves for when we have multiple rows (one for each
|
||||||
await self.db_pool.simple_select_one(
|
# instance). So to handle that case we take the minimum of all rows.
|
||||||
table="device_lists_changes_converted_stream_position",
|
rows = await self.db_pool.simple_select_list(
|
||||||
keyvalues={},
|
table="device_lists_changes_converted_stream_position",
|
||||||
retcols=["stream_id", "room_id"],
|
keyvalues={},
|
||||||
desc="get_device_change_last_converted_pos",
|
retcols=["stream_id", "room_id"],
|
||||||
),
|
desc="get_device_change_last_converted_pos",
|
||||||
)
|
)
|
||||||
|
return cast(Tuple[int, str], min(rows))
|
||||||
|
|
||||||
async def set_device_change_last_converted_pos(
|
async def set_device_change_last_converted_pos(
|
||||||
self,
|
self,
|
||||||
|
@ -2417,6 +2423,10 @@ class DeviceStore(DeviceWorkerStore, DeviceBackgroundUpdateStore):
|
||||||
await self.db_pool.simple_update_one(
|
await self.db_pool.simple_update_one(
|
||||||
table="device_lists_changes_converted_stream_position",
|
table="device_lists_changes_converted_stream_position",
|
||||||
keyvalues={},
|
keyvalues={},
|
||||||
updatevalues={"stream_id": stream_id, "room_id": room_id},
|
updatevalues={
|
||||||
|
"stream_id": stream_id,
|
||||||
|
"instance_name": self._instance_name,
|
||||||
|
"room_id": room_id,
|
||||||
|
},
|
||||||
desc="set_device_change_last_converted_pos",
|
desc="set_device_change_last_converted_pos",
|
||||||
)
|
)
|
||||||
|
|
|
@ -2207,6 +2207,7 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore):
|
||||||
super().__init__(database, db_conn, hs)
|
super().__init__(database, db_conn, hs)
|
||||||
|
|
||||||
self._event_reports_id_gen = IdGenerator(db_conn, "event_reports", "id")
|
self._event_reports_id_gen = IdGenerator(db_conn, "event_reports", "id")
|
||||||
|
self._room_reports_id_gen = IdGenerator(db_conn, "room_reports", "id")
|
||||||
|
|
||||||
self._instance_name = hs.get_instance_name()
|
self._instance_name = hs.get_instance_name()
|
||||||
|
|
||||||
|
@ -2416,6 +2417,37 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore):
|
||||||
)
|
)
|
||||||
return next_id
|
return next_id
|
||||||
|
|
||||||
|
async def add_room_report(
|
||||||
|
self,
|
||||||
|
room_id: str,
|
||||||
|
user_id: str,
|
||||||
|
reason: str,
|
||||||
|
received_ts: int,
|
||||||
|
) -> int:
|
||||||
|
"""Add a room report
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room_id: The room ID being reported.
|
||||||
|
user_id: User who reports the room.
|
||||||
|
reason: Description that the user specifies.
|
||||||
|
received_ts: Time when the user submitted the report (milliseconds).
|
||||||
|
Returns:
|
||||||
|
Id of the room report.
|
||||||
|
"""
|
||||||
|
next_id = self._room_reports_id_gen.get_next()
|
||||||
|
await self.db_pool.simple_insert(
|
||||||
|
table="room_reports",
|
||||||
|
values={
|
||||||
|
"id": next_id,
|
||||||
|
"received_ts": received_ts,
|
||||||
|
"room_id": room_id,
|
||||||
|
"user_id": user_id,
|
||||||
|
"reason": reason,
|
||||||
|
},
|
||||||
|
desc="add_room_report",
|
||||||
|
)
|
||||||
|
return next_id
|
||||||
|
|
||||||
async def block_room(self, room_id: str, user_id: str) -> None:
|
async def block_room(self, room_id: str, user_id: str) -> None:
|
||||||
"""Marks the room as blocked.
|
"""Marks the room as blocked.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
--
|
||||||
|
-- This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2024 New Vector, Ltd
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU Affero General Public License as
|
||||||
|
-- published by the Free Software Foundation, either version 3 of the
|
||||||
|
-- License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- See the GNU Affero General Public License for more details:
|
||||||
|
-- <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||||
|
|
||||||
|
-- Add `instance_name` columns to stream tables to allow them to be used with
|
||||||
|
-- `MultiWriterIdGenerator`
|
||||||
|
ALTER TABLE device_lists_changes_converted_stream_position ADD COLUMN instance_name TEXT;
|
20
synapse/storage/schema/main/delta/85/06_add_room_reports.sql
Normal file
20
synapse/storage/schema/main/delta/85/06_add_room_reports.sql
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--
|
||||||
|
-- This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2024 New Vector, Ltd
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU Affero General Public License as
|
||||||
|
-- published by the Free Software Foundation, either version 3 of the
|
||||||
|
-- License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- See the GNU Affero General Public License for more details:
|
||||||
|
-- <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||||
|
|
||||||
|
CREATE TABLE room_reports (
|
||||||
|
id BIGINT NOT NULL PRIMARY KEY,
|
||||||
|
received_ts BIGINT NOT NULL,
|
||||||
|
room_id TEXT NOT NULL,
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
reason TEXT NOT NULL
|
||||||
|
);
|
|
@ -24,7 +24,7 @@ from twisted.test.proto_helpers import MemoryReactor
|
||||||
|
|
||||||
import synapse.rest.admin
|
import synapse.rest.admin
|
||||||
from synapse.api.errors import Codes
|
from synapse.api.errors import Codes
|
||||||
from synapse.rest.client import login, report_event, room
|
from synapse.rest.client import login, reporting, room
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
from synapse.util import Clock
|
from synapse.util import Clock
|
||||||
|
@ -37,7 +37,7 @@ class EventReportsTestCase(unittest.HomeserverTestCase):
|
||||||
synapse.rest.admin.register_servlets,
|
synapse.rest.admin.register_servlets,
|
||||||
login.register_servlets,
|
login.register_servlets,
|
||||||
room.register_servlets,
|
room.register_servlets,
|
||||||
report_event.register_servlets,
|
reporting.register_servlets,
|
||||||
]
|
]
|
||||||
|
|
||||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
@ -453,7 +453,7 @@ class EventReportDetailTestCase(unittest.HomeserverTestCase):
|
||||||
synapse.rest.admin.register_servlets,
|
synapse.rest.admin.register_servlets,
|
||||||
login.register_servlets,
|
login.register_servlets,
|
||||||
room.register_servlets,
|
room.register_servlets,
|
||||||
report_event.register_servlets,
|
reporting.register_servlets,
|
||||||
]
|
]
|
||||||
|
|
||||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
from twisted.test.proto_helpers import MemoryReactor
|
from twisted.test.proto_helpers import MemoryReactor
|
||||||
|
|
||||||
import synapse.rest.admin
|
import synapse.rest.admin
|
||||||
from synapse.rest.client import login, report_event, room
|
from synapse.rest.client import login, reporting, room
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
from synapse.util import Clock
|
from synapse.util import Clock
|
||||||
|
@ -35,7 +35,7 @@ class ReportEventTestCase(unittest.HomeserverTestCase):
|
||||||
synapse.rest.admin.register_servlets,
|
synapse.rest.admin.register_servlets,
|
||||||
login.register_servlets,
|
login.register_servlets,
|
||||||
room.register_servlets,
|
room.register_servlets,
|
||||||
report_event.register_servlets,
|
reporting.register_servlets,
|
||||||
]
|
]
|
||||||
|
|
||||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
@ -139,3 +139,92 @@ class ReportEventTestCase(unittest.HomeserverTestCase):
|
||||||
"POST", self.report_path, data, access_token=self.other_user_tok
|
"POST", self.report_path, data, access_token=self.other_user_tok
|
||||||
)
|
)
|
||||||
self.assertEqual(response_status, channel.code, msg=channel.result["body"])
|
self.assertEqual(response_status, channel.code, msg=channel.result["body"])
|
||||||
|
|
||||||
|
|
||||||
|
class ReportRoomTestCase(unittest.HomeserverTestCase):
|
||||||
|
servlets = [
|
||||||
|
synapse.rest.admin.register_servlets,
|
||||||
|
login.register_servlets,
|
||||||
|
room.register_servlets,
|
||||||
|
reporting.register_servlets,
|
||||||
|
]
|
||||||
|
|
||||||
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
self.other_user = self.register_user("user", "pass")
|
||||||
|
self.other_user_tok = self.login("user", "pass")
|
||||||
|
|
||||||
|
self.room_id = self.helper.create_room_as(
|
||||||
|
self.other_user, tok=self.other_user_tok, is_public=True
|
||||||
|
)
|
||||||
|
self.report_path = (
|
||||||
|
f"/_matrix/client/unstable/org.matrix.msc4151/rooms/{self.room_id}/report"
|
||||||
|
)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4151_enabled": True},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_reason_str(self) -> None:
|
||||||
|
data = {"reason": "this makes me sad"}
|
||||||
|
self._assert_status(200, data)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4151_enabled": True},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_no_reason(self) -> None:
|
||||||
|
data = {"not_reason": "for typechecking"}
|
||||||
|
self._assert_status(400, data)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4151_enabled": True},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_reason_nonstring(self) -> None:
|
||||||
|
data = {"reason": 42}
|
||||||
|
self._assert_status(400, data)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4151_enabled": True},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_reason_null(self) -> None:
|
||||||
|
data = {"reason": None}
|
||||||
|
self._assert_status(400, data)
|
||||||
|
|
||||||
|
@unittest.override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4151_enabled": True},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_cannot_report_nonexistent_room(self) -> None:
|
||||||
|
"""
|
||||||
|
Tests that we don't accept event reports for rooms which do not exist.
|
||||||
|
"""
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
"/_matrix/client/unstable/org.matrix.msc4151/rooms/!bloop:example.org/report",
|
||||||
|
{"reason": "i am very sad"},
|
||||||
|
access_token=self.other_user_tok,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(404, channel.code, msg=channel.result["body"])
|
||||||
|
self.assertEqual(
|
||||||
|
"Room does not exist",
|
||||||
|
channel.json_body["error"],
|
||||||
|
msg=channel.result["body"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _assert_status(self, response_status: int, data: JsonDict) -> None:
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
self.report_path,
|
||||||
|
data,
|
||||||
|
access_token=self.other_user_tok,
|
||||||
|
shorthand=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(response_status, channel.code, msg=channel.result["body"])
|
Loading…
Reference in a new issue