mirror of
https://github.com/element-hq/synapse.git
synced 2025-07-04 00:00:27 -04:00
Compare commits
10 Commits
1a44634122
...
7e09a4d233
Author | SHA1 | Date | |
---|---|---|---|
|
7e09a4d233 | ||
|
6ddbb03612 | ||
|
cc8da2c5ed | ||
|
c17fd947f3 | ||
|
24bcdb3f3c | ||
|
e3ed93adf3 | ||
|
214ac2f005 | ||
|
c471e84697 | ||
|
291880012f | ||
|
a2bee2f255 |
4
.github/workflows/release-artifacts.yml
vendored
4
.github/workflows/release-artifacts.yml
vendored
@ -111,7 +111,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, macos-13]
|
os: [ubuntu-24.04, macos-13]
|
||||||
arch: [x86_64, aarch64]
|
arch: [x86_64, aarch64]
|
||||||
# is_pr is a flag used to exclude certain jobs from the matrix on PRs.
|
# is_pr is a flag used to exclude certain jobs from the matrix on PRs.
|
||||||
# It is not read by the rest of the workflow.
|
# It is not read by the rest of the workflow.
|
||||||
@ -139,7 +139,7 @@ jobs:
|
|||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: python -m pip install cibuildwheel==2.23.0
|
run: python -m pip install cibuildwheel==3.0.0
|
||||||
|
|
||||||
- name: Set up QEMU to emulate aarch64
|
- name: Set up QEMU to emulate aarch64
|
||||||
if: matrix.arch == 'aarch64'
|
if: matrix.arch == 'aarch64'
|
||||||
|
18
CHANGES.md
18
CHANGES.md
@ -1,3 +1,21 @@
|
|||||||
|
# Synapse 1.133.0 (2025-07-01)
|
||||||
|
|
||||||
|
Pre-built wheels are now built using the [manylinux_2_28](https://github.com/pypa/manylinux#manylinux_2_28-almalinux-8-based) base, which is expected to be compatible with distros using glibc 2.28 or later, including:
|
||||||
|
|
||||||
|
- Debian 10+
|
||||||
|
- Ubuntu 18.10+
|
||||||
|
- Fedora 29+
|
||||||
|
- CentOS/RHEL 8+
|
||||||
|
|
||||||
|
Previously, wheels were built using the [manylinux2014](https://github.com/pypa/manylinux#manylinux2014-centos-7-based-glibc-217) base, which was expected to be compatible with distros using glibc 2.17 or later.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Bump `cibuildwheel` to 3.0.0 to fix the `manylinux` wheel builds. ([\#18615](https://github.com/element-hq/synapse/issues/18615))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Synapse 1.133.0rc1 (2025-06-24)
|
# Synapse 1.133.0rc1 (2025-06-24)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
1
changelog.d/18070.feature
Normal file
1
changelog.d/18070.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support for [MSC4235](https://github.com/matrix-org/matrix-spec-proposals/pull/4235): via query param for hierarchy endpoint. Contributed by Krishan (@kfiven).
|
1
changelog.d/18418.removal
Normal file
1
changelog.d/18418.removal
Normal file
@ -0,0 +1 @@
|
|||||||
|
Stop adding the "origin" field to newly-created events (PDUs).
|
1
changelog.d/18519.doc
Normal file
1
changelog.d/18519.doc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix documentation of the Delete Room Admin API's status field.
|
1
changelog.d/18575.misc
Normal file
1
changelog.d/18575.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Raise poetry-core version cap to 2.1.3.
|
1
changelog.d/18625.misc
Normal file
1
changelog.d/18625.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Log the room ID we're purging state for.
|
@ -45,6 +45,10 @@ def make_graph(pdus: List[dict], filename_prefix: str) -> None:
|
|||||||
colors = {"red", "green", "blue", "yellow", "purple"}
|
colors = {"red", "green", "blue", "yellow", "purple"}
|
||||||
|
|
||||||
for pdu in pdus:
|
for pdu in pdus:
|
||||||
|
# TODO: The "origin" field has since been removed from events generated
|
||||||
|
# by Synapse. We should consider removing it here as well but since this
|
||||||
|
# is part of `contrib/`, it is left for the community to revise and ensure things
|
||||||
|
# still work correctly.
|
||||||
origins.add(pdu.get("origin"))
|
origins.add(pdu.get("origin"))
|
||||||
|
|
||||||
color_map = {color: color for color in colors if color in origins}
|
color_map = {color: color for color in colors if color in origins}
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
matrix-synapse-py3 (1.133.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* New synapse release 1.133.0.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 01 Jul 2025 13:13:24 +0000
|
||||||
|
|
||||||
matrix-synapse-py3 (1.133.0~rc1) stable; urgency=medium
|
matrix-synapse-py3 (1.133.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
* New Synapse release 1.133.0rc1.
|
* New Synapse release 1.133.0rc1.
|
||||||
|
@ -117,7 +117,6 @@ It returns a JSON body like the following:
|
|||||||
"hashes": {
|
"hashes": {
|
||||||
"sha256": "xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw"
|
"sha256": "xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw"
|
||||||
},
|
},
|
||||||
"origin": "matrix.org",
|
|
||||||
"origin_server_ts": 1592291711430,
|
"origin_server_ts": 1592291711430,
|
||||||
"prev_events": [
|
"prev_events": [
|
||||||
"$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M"
|
"$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M"
|
||||||
|
@ -806,7 +806,7 @@ A response body like the following is returned:
|
|||||||
}, {
|
}, {
|
||||||
"delete_id": "delete_id2",
|
"delete_id": "delete_id2",
|
||||||
"room_id": "!roomid:example.com",
|
"room_id": "!roomid:example.com",
|
||||||
"status": "purging",
|
"status": "active",
|
||||||
"shutdown_room": {
|
"shutdown_room": {
|
||||||
"kicked_users": [
|
"kicked_users": [
|
||||||
"@foobar:example.com"
|
"@foobar:example.com"
|
||||||
@ -843,7 +843,7 @@ A response body like the following is returned:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "purging",
|
"status": "active",
|
||||||
"delete_id": "bHkCNQpHqOaFhPtK",
|
"delete_id": "bHkCNQpHqOaFhPtK",
|
||||||
"room_id": "!roomid:example.com",
|
"room_id": "!roomid:example.com",
|
||||||
"shutdown_room": {
|
"shutdown_room": {
|
||||||
@ -876,8 +876,8 @@ The following fields are returned in the JSON response body:
|
|||||||
- `delete_id` - The ID for this purge
|
- `delete_id` - The ID for this purge
|
||||||
- `room_id` - The ID of the room being deleted
|
- `room_id` - The ID of the room being deleted
|
||||||
- `status` - The status will be one of:
|
- `status` - The status will be one of:
|
||||||
- `shutting_down` - The process is removing users from the room.
|
- `scheduled` - The deletion is waiting to be started
|
||||||
- `purging` - The process is purging the room and event data from database.
|
- `active` - The process is purging the room and event data from database.
|
||||||
- `complete` - The process has completed successfully.
|
- `complete` - The process has completed successfully.
|
||||||
- `failed` - The process is aborted, an error has occurred.
|
- `failed` - The process is aborted, an error has occurred.
|
||||||
- `error` - A string that shows an error message if `status` is `failed`.
|
- `error` - A string that shows an error message if `status` is `failed`.
|
||||||
|
@ -101,7 +101,7 @@ module-name = "synapse.synapse_rust"
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "matrix-synapse"
|
name = "matrix-synapse"
|
||||||
version = "1.133.0rc1"
|
version = "1.133.0"
|
||||||
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"
|
||||||
@ -374,7 +374,7 @@ tomli = ">=1.2.3"
|
|||||||
# runtime errors caused by build system changes.
|
# runtime errors caused by build system changes.
|
||||||
# We are happy to raise these upper bounds upon request,
|
# We are happy to raise these upper bounds upon request,
|
||||||
# provided we check that it's safe to do so (i.e. that CI passes).
|
# provided we check that it's safe to do so (i.e. that CI passes).
|
||||||
requires = ["poetry-core>=1.1.0,<=1.9.1", "setuptools_rust>=1.3,<=1.10.2"]
|
requires = ["poetry-core>=1.1.0,<=2.1.3", "setuptools_rust>=1.3,<=1.10.2"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
|
@ -561,6 +561,9 @@ class ExperimentalConfig(Config):
|
|||||||
# MSC4076: Add `disable_badge_count`` to pusher configuration
|
# MSC4076: Add `disable_badge_count`` to pusher configuration
|
||||||
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
|
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
|
||||||
|
|
||||||
|
# MSC4235: Add `via` param to hierarchy endpoint
|
||||||
|
self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False)
|
||||||
|
|
||||||
# MSC4263: Preventing MXID enumeration via key queries
|
# MSC4263: Preventing MXID enumeration via key queries
|
||||||
self.msc4263_limit_key_queries_to_users_who_share_rooms = experimental.get(
|
self.msc4263_limit_key_queries_to_users_who_share_rooms = experimental.get(
|
||||||
"msc4263_limit_key_queries_to_users_who_share_rooms",
|
"msc4263_limit_key_queries_to_users_who_share_rooms",
|
||||||
|
@ -208,7 +208,6 @@ class EventBase(metaclass=abc.ABCMeta):
|
|||||||
depth: DictProperty[int] = DictProperty("depth")
|
depth: DictProperty[int] = DictProperty("depth")
|
||||||
content: DictProperty[JsonDict] = DictProperty("content")
|
content: DictProperty[JsonDict] = DictProperty("content")
|
||||||
hashes: DictProperty[Dict[str, str]] = DictProperty("hashes")
|
hashes: DictProperty[Dict[str, str]] = DictProperty("hashes")
|
||||||
origin: DictProperty[str] = DictProperty("origin")
|
|
||||||
origin_server_ts: DictProperty[int] = DictProperty("origin_server_ts")
|
origin_server_ts: DictProperty[int] = DictProperty("origin_server_ts")
|
||||||
room_id: DictProperty[str] = DictProperty("room_id")
|
room_id: DictProperty[str] = DictProperty("room_id")
|
||||||
sender: DictProperty[str] = DictProperty("sender")
|
sender: DictProperty[str] = DictProperty("sender")
|
||||||
|
@ -302,8 +302,8 @@ def create_local_event_from_event_dict(
|
|||||||
event_dict: JsonDict,
|
event_dict: JsonDict,
|
||||||
internal_metadata_dict: Optional[JsonDict] = None,
|
internal_metadata_dict: Optional[JsonDict] = None,
|
||||||
) -> EventBase:
|
) -> EventBase:
|
||||||
"""Takes a fully formed event dict, ensuring that fields like `origin`
|
"""Takes a fully formed event dict, ensuring that fields like
|
||||||
and `origin_server_ts` have correct values for a locally produced event,
|
`origin_server_ts` have correct values for a locally produced event,
|
||||||
then signs and hashes it.
|
then signs and hashes it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -319,7 +319,6 @@ def create_local_event_from_event_dict(
|
|||||||
if format_version == EventFormatVersions.ROOM_V1_V2:
|
if format_version == EventFormatVersions.ROOM_V1_V2:
|
||||||
event_dict["event_id"] = _create_event_id(clock, hostname)
|
event_dict["event_id"] = _create_event_id(clock, hostname)
|
||||||
|
|
||||||
event_dict["origin"] = hostname
|
|
||||||
event_dict.setdefault("origin_server_ts", time_now)
|
event_dict.setdefault("origin_server_ts", time_now)
|
||||||
|
|
||||||
event_dict.setdefault("unsigned", {})
|
event_dict.setdefault("unsigned", {})
|
||||||
|
@ -67,7 +67,6 @@ class EventValidator:
|
|||||||
"auth_events",
|
"auth_events",
|
||||||
"content",
|
"content",
|
||||||
"hashes",
|
"hashes",
|
||||||
"origin",
|
|
||||||
"prev_events",
|
"prev_events",
|
||||||
"sender",
|
"sender",
|
||||||
"type",
|
"type",
|
||||||
@ -77,13 +76,6 @@ class EventValidator:
|
|||||||
if k not in event:
|
if k not in event:
|
||||||
raise SynapseError(400, "Event does not have key %s" % (k,))
|
raise SynapseError(400, "Event does not have key %s" % (k,))
|
||||||
|
|
||||||
# Check that the following keys have string values
|
|
||||||
event_strings = ["origin"]
|
|
||||||
|
|
||||||
for s in event_strings:
|
|
||||||
if not isinstance(getattr(event, s), str):
|
|
||||||
raise SynapseError(400, "'%s' not a string type" % (s,))
|
|
||||||
|
|
||||||
# Depending on the room version, ensure the data is spec compliant JSON.
|
# Depending on the room version, ensure the data is spec compliant JSON.
|
||||||
if event.room_version.strict_canonicaljson:
|
if event.room_version.strict_canonicaljson:
|
||||||
validate_canonicaljson(event.get_pdu_json())
|
validate_canonicaljson(event.get_pdu_json())
|
||||||
|
@ -323,8 +323,7 @@ def event_from_pdu_json(pdu_json: JsonDict, room_version: RoomVersion) -> EventB
|
|||||||
SynapseError: if the pdu is missing required fields or is otherwise
|
SynapseError: if the pdu is missing required fields or is otherwise
|
||||||
not a valid matrix event
|
not a valid matrix event
|
||||||
"""
|
"""
|
||||||
# we could probably enforce a bunch of other fields here (room_id, sender,
|
# we could probably enforce a bunch of other fields here (room_id, sender, etc.)
|
||||||
# origin, etc etc)
|
|
||||||
assert_params_in_dict(pdu_json, ("type", "depth"))
|
assert_params_in_dict(pdu_json, ("type", "depth"))
|
||||||
|
|
||||||
# Strip any unauthorized values from "unsigned" if they exist
|
# Strip any unauthorized values from "unsigned" if they exist
|
||||||
|
@ -111,7 +111,15 @@ class RoomSummaryHandler:
|
|||||||
# If a user tries to fetch the same page multiple times in quick succession,
|
# If a user tries to fetch the same page multiple times in quick succession,
|
||||||
# only process the first attempt and return its result to subsequent requests.
|
# only process the first attempt and return its result to subsequent requests.
|
||||||
self._pagination_response_cache: ResponseCache[
|
self._pagination_response_cache: ResponseCache[
|
||||||
Tuple[str, str, bool, Optional[int], Optional[int], Optional[str]]
|
Tuple[
|
||||||
|
str,
|
||||||
|
str,
|
||||||
|
bool,
|
||||||
|
Optional[int],
|
||||||
|
Optional[int],
|
||||||
|
Optional[str],
|
||||||
|
Optional[Tuple[str, ...]],
|
||||||
|
]
|
||||||
] = ResponseCache(
|
] = ResponseCache(
|
||||||
hs.get_clock(),
|
hs.get_clock(),
|
||||||
"get_room_hierarchy",
|
"get_room_hierarchy",
|
||||||
@ -126,6 +134,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth: Optional[int] = None,
|
max_depth: Optional[int] = None,
|
||||||
limit: Optional[int] = None,
|
limit: Optional[int] = None,
|
||||||
from_token: Optional[str] = None,
|
from_token: Optional[str] = None,
|
||||||
|
remote_room_hosts: Optional[Tuple[str, ...]] = None,
|
||||||
) -> JsonDict:
|
) -> JsonDict:
|
||||||
"""
|
"""
|
||||||
Implementation of the room hierarchy C-S API.
|
Implementation of the room hierarchy C-S API.
|
||||||
@ -143,6 +152,9 @@ class RoomSummaryHandler:
|
|||||||
limit: An optional limit on the number of rooms to return per
|
limit: An optional limit on the number of rooms to return per
|
||||||
page. Must be a positive integer.
|
page. Must be a positive integer.
|
||||||
from_token: An optional pagination token.
|
from_token: An optional pagination token.
|
||||||
|
remote_room_hosts: An optional list of remote homeserver server names. If defined,
|
||||||
|
each host will be used to try and fetch the room hierarchy. Must be a tuple so
|
||||||
|
that it can be hashed by the `RoomSummaryHandler._pagination_response_cache`.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The JSON hierarchy dictionary.
|
The JSON hierarchy dictionary.
|
||||||
@ -162,6 +174,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth,
|
max_depth,
|
||||||
limit,
|
limit,
|
||||||
from_token,
|
from_token,
|
||||||
|
remote_room_hosts,
|
||||||
),
|
),
|
||||||
self._get_room_hierarchy,
|
self._get_room_hierarchy,
|
||||||
requester.user.to_string(),
|
requester.user.to_string(),
|
||||||
@ -170,6 +183,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth,
|
max_depth,
|
||||||
limit,
|
limit,
|
||||||
from_token,
|
from_token,
|
||||||
|
remote_room_hosts,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _get_room_hierarchy(
|
async def _get_room_hierarchy(
|
||||||
@ -180,6 +194,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth: Optional[int] = None,
|
max_depth: Optional[int] = None,
|
||||||
limit: Optional[int] = None,
|
limit: Optional[int] = None,
|
||||||
from_token: Optional[str] = None,
|
from_token: Optional[str] = None,
|
||||||
|
remote_room_hosts: Optional[Tuple[str, ...]] = None,
|
||||||
) -> JsonDict:
|
) -> JsonDict:
|
||||||
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
|
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
|
||||||
|
|
||||||
@ -199,7 +214,7 @@ class RoomSummaryHandler:
|
|||||||
|
|
||||||
if not local_room:
|
if not local_room:
|
||||||
room_hierarchy = await self._summarize_remote_room_hierarchy(
|
room_hierarchy = await self._summarize_remote_room_hierarchy(
|
||||||
_RoomQueueEntry(requested_room_id, ()),
|
_RoomQueueEntry(requested_room_id, remote_room_hosts or ()),
|
||||||
False,
|
False,
|
||||||
)
|
)
|
||||||
root_room_entry = room_hierarchy[0]
|
root_room_entry = room_hierarchy[0]
|
||||||
@ -240,7 +255,7 @@ class RoomSummaryHandler:
|
|||||||
processed_rooms = set(pagination_session["processed_rooms"])
|
processed_rooms = set(pagination_session["processed_rooms"])
|
||||||
else:
|
else:
|
||||||
# The queue of rooms to process, the next room is last on the stack.
|
# The queue of rooms to process, the next room is last on the stack.
|
||||||
room_queue = [_RoomQueueEntry(requested_room_id, ())]
|
room_queue = [_RoomQueueEntry(requested_room_id, remote_room_hosts or ())]
|
||||||
|
|
||||||
# Rooms we have already processed.
|
# Rooms we have already processed.
|
||||||
processed_rooms = set()
|
processed_rooms = set()
|
||||||
|
@ -1538,6 +1538,7 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._auth = hs.get_auth()
|
self._auth = hs.get_auth()
|
||||||
self._room_summary_handler = hs.get_room_summary_handler()
|
self._room_summary_handler = hs.get_room_summary_handler()
|
||||||
|
self.msc4235_enabled = hs.config.experimental.msc4235_enabled
|
||||||
|
|
||||||
async def on_GET(
|
async def on_GET(
|
||||||
self, request: SynapseRequest, room_id: str
|
self, request: SynapseRequest, room_id: str
|
||||||
@ -1547,6 +1548,15 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
max_depth = parse_integer(request, "max_depth")
|
max_depth = parse_integer(request, "max_depth")
|
||||||
limit = parse_integer(request, "limit")
|
limit = parse_integer(request, "limit")
|
||||||
|
|
||||||
|
# twisted.web.server.Request.args is incorrectly defined as Optional[Any]
|
||||||
|
remote_room_hosts = None
|
||||||
|
if self.msc4235_enabled:
|
||||||
|
args: Dict[bytes, List[bytes]] = request.args # type: ignore
|
||||||
|
via_param = parse_strings_from_args(
|
||||||
|
args, "org.matrix.msc4235.via", required=False
|
||||||
|
)
|
||||||
|
remote_room_hosts = tuple(via_param or [])
|
||||||
|
|
||||||
return 200, await self._room_summary_handler.get_room_hierarchy(
|
return 200, await self._room_summary_handler.get_room_hierarchy(
|
||||||
requester,
|
requester,
|
||||||
room_id,
|
room_id,
|
||||||
@ -1554,6 +1564,7 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
max_depth=max_depth,
|
max_depth=max_depth,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
from_token=parse_string(request, "from"),
|
from_token=parse_string(request, "from"),
|
||||||
|
remote_room_hosts=remote_room_hosts,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ from synapse.metrics.background_process_metrics import wrap_as_background_proces
|
|||||||
from synapse.storage.database import LoggingTransaction
|
from synapse.storage.database import LoggingTransaction
|
||||||
from synapse.storage.databases import Databases
|
from synapse.storage.databases import Databases
|
||||||
from synapse.types.storage import _BackgroundUpdates
|
from synapse.types.storage import _BackgroundUpdates
|
||||||
|
from synapse.util.stringutils import shortstr
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
@ -167,6 +168,12 @@ class PurgeEventsStorageController:
|
|||||||
break
|
break
|
||||||
|
|
||||||
(room_id, groups_to_sequences) = next_to_delete
|
(room_id, groups_to_sequences) = next_to_delete
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"[purge] deleting state groups for room %s: %s",
|
||||||
|
room_id,
|
||||||
|
shortstr(groups_to_sequences.keys(), maxitems=10),
|
||||||
|
)
|
||||||
made_progress = await self._delete_state_groups(
|
made_progress = await self._delete_state_groups(
|
||||||
room_id, groups_to_sequences
|
room_id, groups_to_sequences
|
||||||
)
|
)
|
||||||
|
@ -225,7 +225,7 @@ KNOWN_KEYS = {
|
|||||||
"depth",
|
"depth",
|
||||||
"event_id",
|
"event_id",
|
||||||
"hashes",
|
"hashes",
|
||||||
"origin",
|
"origin", # old events were created with an origin field.
|
||||||
"origin_server_ts",
|
"origin_server_ts",
|
||||||
"prev_events",
|
"prev_events",
|
||||||
"room_id",
|
"room_id",
|
||||||
|
@ -48,7 +48,6 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
def test_sign_minimal(self) -> None:
|
def test_sign_minimal(self) -> None:
|
||||||
event_dict = {
|
event_dict = {
|
||||||
"event_id": "$0:domain",
|
"event_id": "$0:domain",
|
||||||
"origin": "domain",
|
|
||||||
"origin_server_ts": 1000000,
|
"origin_server_ts": 1000000,
|
||||||
"signatures": {},
|
"signatures": {},
|
||||||
"type": "X",
|
"type": "X",
|
||||||
@ -64,7 +63,7 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertTrue(hasattr(event, "hashes"))
|
self.assertTrue(hasattr(event, "hashes"))
|
||||||
self.assertIn("sha256", event.hashes)
|
self.assertIn("sha256", event.hashes)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.hashes["sha256"], "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI"
|
event.hashes["sha256"], "A6Nco6sqoy18PPfPDVdYvoowfc0PVBk9g9OiyT3ncRM"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(hasattr(event, "signatures"))
|
self.assertTrue(hasattr(event, "signatures"))
|
||||||
@ -72,15 +71,14 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertIn(KEY_NAME, event.signatures["domain"])
|
self.assertIn(KEY_NAME, event.signatures["domain"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.signatures[HOSTNAME][KEY_NAME],
|
event.signatures[HOSTNAME][KEY_NAME],
|
||||||
"2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+"
|
"PBc48yDVszWB9TRaB/+CZC1B+pDAC10F8zll006j+NN"
|
||||||
"aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA",
|
"fe4PEMWcVuLaG63LFTK9e4rwJE8iLZMPtCKhDTXhpAQ",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_sign_message(self) -> None:
|
def test_sign_message(self) -> None:
|
||||||
event_dict = {
|
event_dict = {
|
||||||
"content": {"body": "Here is the message content"},
|
"content": {"body": "Here is the message content"},
|
||||||
"event_id": "$0:domain",
|
"event_id": "$0:domain",
|
||||||
"origin": "domain",
|
|
||||||
"origin_server_ts": 1000000,
|
"origin_server_ts": 1000000,
|
||||||
"type": "m.room.message",
|
"type": "m.room.message",
|
||||||
"room_id": "!r:domain",
|
"room_id": "!r:domain",
|
||||||
@ -98,7 +96,7 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertTrue(hasattr(event, "hashes"))
|
self.assertTrue(hasattr(event, "hashes"))
|
||||||
self.assertIn("sha256", event.hashes)
|
self.assertIn("sha256", event.hashes)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.hashes["sha256"], "onLKD1bGljeBWQhWZ1kaP9SorVmRQNdN5aM2JYU2n/g"
|
event.hashes["sha256"], "rDCeYBepPlI891h/RkI2/Lkf9bt7u0TxFku4tMs7WKk"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(hasattr(event, "signatures"))
|
self.assertTrue(hasattr(event, "signatures"))
|
||||||
@ -106,6 +104,6 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertIn(KEY_NAME, event.signatures["domain"])
|
self.assertIn(KEY_NAME, event.signatures["domain"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.signatures[HOSTNAME][KEY_NAME],
|
event.signatures[HOSTNAME][KEY_NAME],
|
||||||
"Wm+VzmOUOz08Ds+0NTWb1d4CZrVsJSikkeRxh6aCcUw"
|
"Ay4aj2b5oJ1k8INYZ9n3KnszCflM0emwcmQQ7vxpbdc"
|
||||||
"u6pNC78FunoD7KNWzqFn241eYHYMGCA5McEiVPdhzBA",
|
"Sv9bkJxIZdWX1IJllcZLq89+D3sSabE+vqPtZs9akDw",
|
||||||
)
|
)
|
||||||
|
@ -130,7 +130,7 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
"prev_events": "prev_events",
|
"prev_events": "prev_events",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"auth_events": "auth_events",
|
"auth_events": "auth_events",
|
||||||
"origin": "domain",
|
"origin": "domain", # historical top-level field that still exists on old events
|
||||||
"origin_server_ts": 1234,
|
"origin_server_ts": 1234,
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
# Also include a key that should be removed.
|
# Also include a key that should be removed.
|
||||||
@ -147,7 +147,7 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
"prev_events": "prev_events",
|
"prev_events": "prev_events",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"auth_events": "auth_events",
|
"auth_events": "auth_events",
|
||||||
"origin": "domain",
|
"origin": "domain", # historical top-level field that still exists on old events
|
||||||
"origin_server_ts": 1234,
|
"origin_server_ts": 1234,
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
"content": {},
|
"content": {},
|
||||||
@ -156,13 +156,12 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# As of room versions we now redact the membership, prev_states, and origin keys.
|
# As of room versions we now redact the membership and prev_states keys.
|
||||||
self.run_test(
|
self.run_test(
|
||||||
{
|
{
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
"origin": "example.com",
|
|
||||||
},
|
},
|
||||||
{"type": "A", "content": {}, "signatures": {}, "unsigned": {}},
|
{"type": "A", "content": {}, "signatures": {}, "unsigned": {}},
|
||||||
room_version=RoomVersions.V11,
|
room_version=RoomVersions.V11,
|
||||||
@ -246,7 +245,6 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
{
|
{
|
||||||
"type": "m.room.create",
|
"type": "m.room.create",
|
||||||
"content": {"not_a_real_key": True},
|
"content": {"not_a_real_key": True},
|
||||||
"origin": "some_homeserver",
|
|
||||||
"nonsense_field": "some_random_garbage",
|
"nonsense_field": "some_random_garbage",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -535,7 +535,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.member",
|
"type": "m.room.member",
|
||||||
"origin": "test.servx",
|
|
||||||
"content": {"membership": "join"},
|
"content": {"membership": "join"},
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"unsigned": {"malicious garbage": "hackz", "more warez": "more hackz"},
|
"unsigned": {"malicious garbage": "hackz", "more warez": "more hackz"},
|
||||||
@ -552,7 +551,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.member",
|
"type": "m.room.member",
|
||||||
"origin": "test.servx",
|
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"content": {"membership": "join"},
|
"content": {"membership": "join"},
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
@ -579,7 +577,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.power_levels",
|
"type": "m.room.power_levels",
|
||||||
"origin": "test.servx",
|
|
||||||
"content": {},
|
"content": {},
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
|
@ -1080,6 +1080,62 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
|
|||||||
self.assertEqual(federation_requests, 2)
|
self.assertEqual(federation_requests, 2)
|
||||||
self._assert_hierarchy(result, expected)
|
self._assert_hierarchy(result, expected)
|
||||||
|
|
||||||
|
def test_fed_remote_room_hosts(self) -> None:
|
||||||
|
"""
|
||||||
|
Test if requested room is available over federation using via's.
|
||||||
|
"""
|
||||||
|
fed_hostname = self.hs.hostname + "2"
|
||||||
|
fed_space = "#fed_space:" + fed_hostname
|
||||||
|
fed_subroom = "#fed_sub_room:" + fed_hostname
|
||||||
|
|
||||||
|
remote_room_hosts = tuple(fed_hostname)
|
||||||
|
|
||||||
|
requested_room_entry = _RoomEntry(
|
||||||
|
fed_space,
|
||||||
|
{
|
||||||
|
"room_id": fed_space,
|
||||||
|
"world_readable": True,
|
||||||
|
"join_rule": "public",
|
||||||
|
"room_type": RoomTypes.SPACE,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": EventTypes.SpaceChild,
|
||||||
|
"room_id": fed_space,
|
||||||
|
"state_key": fed_subroom,
|
||||||
|
"content": {"via": [fed_hostname]},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
child_room = {
|
||||||
|
"room_id": fed_subroom,
|
||||||
|
"world_readable": True,
|
||||||
|
"join_rule": "public",
|
||||||
|
}
|
||||||
|
|
||||||
|
async def summarize_remote_room_hierarchy(
|
||||||
|
_self: Any, room: Any, suggested_only: bool
|
||||||
|
) -> Tuple[Optional[_RoomEntry], Dict[str, JsonDict], Set[str]]:
|
||||||
|
return requested_room_entry, {fed_subroom: child_room}, set()
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
(fed_space, [fed_subroom]),
|
||||||
|
(fed_subroom, ()),
|
||||||
|
]
|
||||||
|
|
||||||
|
with mock.patch(
|
||||||
|
"synapse.handlers.room_summary.RoomSummaryHandler._summarize_remote_room_hierarchy",
|
||||||
|
new=summarize_remote_room_hierarchy,
|
||||||
|
):
|
||||||
|
result = self.get_success(
|
||||||
|
self.handler.get_room_hierarchy(
|
||||||
|
create_requester(self.user),
|
||||||
|
fed_space,
|
||||||
|
remote_room_hosts=remote_room_hosts,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._assert_hierarchy(result, expected)
|
||||||
|
|
||||||
|
|
||||||
class RoomSummaryTestCase(unittest.HomeserverTestCase):
|
class RoomSummaryTestCase(unittest.HomeserverTestCase):
|
||||||
servlets = [
|
servlets = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user