Add is_encrypted filtering to Sliding Sync /sync

Based on [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575): Sliding Sync
This commit is contained in:
Eric Eastwood 2024-06-06 17:40:16 -05:00
parent 88fe201f00
commit 44088bd4af
3 changed files with 84 additions and 3 deletions

View file

@ -0,0 +1 @@
Add `is_encrypted` filtering to experimental [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575) Sliding Sync `/sync` endpoint.

View file

@ -31,7 +31,7 @@ if TYPE_CHECKING or HAS_PYDANTIC_V2:
else:
from pydantic import Extra
from synapse.api.constants import AccountDataTypes, Membership
from synapse.api.constants import AccountDataTypes, EventTypes, Membership
from synapse.events import EventBase
from synapse.rest.client.models import SlidingSyncBody
from synapse.types import JsonMapping, Requester, RoomStreamToken, StreamToken, UserID
@ -661,8 +661,23 @@ class SlidingSyncHandler:
if filters.spaces:
raise NotImplementedError()
if filters.is_encrypted:
raise NotImplementedError()
# Filter for encrypted rooms
if filters.is_encrypted is not None:
# Make a copy so we don't run into an error: `Set changed size during iteration`
for room_id in list(filtered_room_id_set):
# TODO: Is there a good method to look up all rooms at once? (N+1 query problem)
is_encrypted = (
await self.storage_controllers.state.get_current_state_event(
room_id, EventTypes.RoomEncryption, ""
)
)
# If we're looking for encrypted rooms, filter out rooms that are not
# encrypted and vice versa
if (filters.is_encrypted and not is_encrypted) or (
not filters.is_encrypted and is_encrypted
):
filtered_room_id_set.remove(room_id)
if filters.is_invite:
raise NotImplementedError()

View file

@ -1246,3 +1246,68 @@ class FilterRoomsTestCase(HomeserverTestCase):
)
self.assertEqual(falsy_filtered_room_ids, {room_id})
def test_filter_encrypted_rooms(self) -> None:
"""
Test `filter.is_encrypted` for encrypted rooms
"""
user1_id = self.register_user("user1", "pass")
user1_tok = self.login(user1_id, "pass")
# Create a normal room
room_id = self.helper.create_room_as(
user1_id,
is_public=False,
tok=user1_tok,
)
# Create an encrypted room
encrypted_room_id = self.helper.create_room_as(
user1_id,
is_public=False,
tok=user1_tok,
)
self.helper.send_state(
encrypted_room_id,
EventTypes.RoomEncryption,
{"algorithm": "m.megolm.v1.aes-sha2"},
tok=user1_tok,
)
# TODO: Better way to avoid the circular import? (see
# https://github.com/element-hq/synapse/pull/17187#discussion_r1619492779)
from synapse.handlers.sliding_sync import SlidingSyncConfig
# Try with `is_encrypted=True`
# -----------------------------
truthy_filters = SlidingSyncConfig.SlidingSyncList.Filters(
is_encrypted=True,
)
# Filter the rooms
truthy_filtered_room_ids = self.get_success(
self.sliding_sync_handler.filter_rooms(
UserID.from_string(user1_id),
{room_id, encrypted_room_id},
truthy_filters,
)
)
self.assertEqual(truthy_filtered_room_ids, {encrypted_room_id})
# Try with `is_encrypted=False`
# -----------------------------
falsy_filters = SlidingSyncConfig.SlidingSyncList.Filters(
is_encrypted=False,
)
# Filter the rooms
falsy_filtered_room_ids = self.get_success(
self.sliding_sync_handler.filter_rooms(
UserID.from_string(user1_id),
{room_id, encrypted_room_id},
falsy_filters,
)
)
self.assertEqual(falsy_filtered_room_ids, {room_id})