Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add is_encrypted filtering to Sliding Sync /sync #17249

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/17249.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `is_encrypted` filtering to experimental [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575) Sliding Sync `/sync` endpoint.
23 changes: 20 additions & 3 deletions synapse/handlers/sliding_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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
Expand Down Expand Up @@ -271,6 +271,8 @@ async def current_sync_for_user(
# Apply filters
filtered_room_ids = room_id_set
if list_config.filters is not None:
# TODO: To be absolutely correct, this could also take into account
# from/to tokens
filtered_room_ids = await self.filter_rooms(
sync_config.user, room_id_set, list_config.filters
)
Expand Down Expand Up @@ -576,8 +578,23 @@ async def filter_rooms(
space_child_room_ids
)

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()
Expand Down
113 changes: 77 additions & 36 deletions tests/handlers/test_sliding_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,59 +668,35 @@ def test_filter_dm_rooms(self) -> None:
# https://github.com/element-hq/synapse/pull/17187#discussion_r1619492779)
from synapse.handlers.sliding_sync import SlidingSyncConfig

filters = SlidingSyncConfig.SlidingSyncList.Filters(
# Try with `is_dm=True`
# -----------------------------
truthy_filters = SlidingSyncConfig.SlidingSyncList.Filters(
is_dm=True,
)

# Try filtering the rooms
filtered_room_ids = self.get_success(
truthy_filtered_room_ids = self.get_success(
self.sliding_sync_handler.filter_rooms(
UserID.from_string(user1_id), {room_id, dm_room_id}, filters
UserID.from_string(user1_id), {room_id, dm_room_id}, truthy_filters
)
)

self.assertEqual(filtered_room_ids, {dm_room_id})

def test_filter_non_dm_rooms(self) -> None:
"""
Test `filter.is_dm` for non-DM rooms
"""
user1_id = self.register_user("user1", "pass")
user1_tok = self.login(user1_id, "pass")
user2_id = self.register_user("user2", "pass")
user2_tok = self.login(user2_id, "pass")

# Create a normal room
room_id = self.helper.create_room_as(
user1_id,
is_public=False,
tok=user1_tok,
)

# Create a DM room
dm_room_id = self._create_dm_room(
inviter_user_id=user1_id,
inviter_tok=user1_tok,
invitee_user_id=user2_id,
invitee_tok=user2_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
self.assertEqual(truthy_filtered_room_ids, {dm_room_id})

filters = SlidingSyncConfig.SlidingSyncList.Filters(
# Try with `is_dm=True`
# -----------------------------
falsy_filters = SlidingSyncConfig.SlidingSyncList.Filters(
is_dm=False,
)

# Try filtering the rooms
filtered_room_ids = self.get_success(
falsy_filtered_room_ids = self.get_success(
self.sliding_sync_handler.filter_rooms(
UserID.from_string(user1_id), {room_id, dm_room_id}, filters
UserID.from_string(user1_id), {room_id, dm_room_id}, falsy_filters
)
)

self.assertEqual(filtered_room_ids, {room_id})
self.assertEqual(falsy_filtered_room_ids, {room_id})

def test_filter_space_rooms(self) -> None:
"""
Expand Down Expand Up @@ -894,3 +870,68 @@ def test_filter_only_joined_spaces(self) -> None:
)

self.assertEqual(filtered_room_ids, {room_id1})

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,
)

# Try filtering 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,
)

# Try filtering 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})
Loading