Skip to content

Commit 034c5e6

Browse files
Move call invite filtering logic to filter_events_for_client (#17782)
1 parent 778897a commit 034c5e6

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

changelog.d/17782.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve event filtering for Simplified Sliding Sync.

synapse/handlers/sliding_sync/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,6 @@ async def get_room_sync_data(
761761
!= Membership.JOIN,
762762
filter_send_to_client=True,
763763
)
764-
# TODO: Filter out `EventTypes.CallInvite` in public rooms,
765-
# see https://github.com/element-hq/synapse/issues/17359
766764

767765
# TODO: Handle timeline gaps (`get_timeline_gaps()`)
768766

synapse/handlers/sync.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
Direction,
3737
EventContentFields,
3838
EventTypes,
39-
JoinRules,
4039
Membership,
4140
)
4241
from synapse.api.filtering import FilterCollection
@@ -790,22 +789,13 @@ async def _load_filtered_recents(
790789
)
791790
)
792791

793-
filtered_recents = await filter_events_for_client(
792+
loaded_recents = await filter_events_for_client(
794793
self._storage_controllers,
795794
sync_config.user.to_string(),
796795
loaded_recents,
797796
always_include_ids=current_state_ids,
798797
)
799798

800-
loaded_recents = []
801-
for event in filtered_recents:
802-
if event.type == EventTypes.CallInvite:
803-
room_info = await self.store.get_room_with_stats(event.room_id)
804-
assert room_info is not None
805-
if room_info.join_rules == JoinRules.PUBLIC:
806-
continue
807-
loaded_recents.append(event)
808-
809799
log_kv({"loaded_recents_after_client_filtering": len(loaded_recents)})
810800

811801
loaded_recents.extend(recents)

synapse/visibility.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
EventTypes,
3434
EventUnsignedContentFields,
3535
HistoryVisibility,
36+
JoinRules,
3637
Membership,
3738
)
3839
from synapse.events import EventBase
@@ -111,7 +112,17 @@ async def filter_events_for_client(
111112
# happen within the function.
112113
events_before_filtering = events.copy()
113114
# Default case is to *exclude* soft-failed events
114-
events = [e for e in events if not e.internal_metadata.is_soft_failed()]
115+
events = []
116+
found_call_invite = False
117+
for event in events_before_filtering:
118+
if event.internal_metadata.is_soft_failed():
119+
continue
120+
121+
if event.type == EventTypes.CallInvite and not event.is_state():
122+
found_call_invite = True
123+
124+
events.append(event)
125+
115126
client_config = await storage.main.get_admin_client_config_for_user(user_id)
116127
if filter_send_to_client and await storage.main.is_server_admin(user_id):
117128
if client_config.return_soft_failed_events:
@@ -139,7 +150,11 @@ async def filter_events_for_client(
139150
[event.event_id for event in events],
140151
)
141152

142-
types = (_HISTORY_VIS_KEY, (EventTypes.Member, user_id))
153+
types = [_HISTORY_VIS_KEY, (EventTypes.Member, user_id)]
154+
if found_call_invite:
155+
# We need to fetch the room's join rules state to determine
156+
# whether to allow call invites in public rooms.
157+
types.append((EventTypes.JoinRules, ""))
143158

144159
# we exclude outliers at this point, and then handle them separately later
145160
event_id_to_state = await storage.state.get_state_for_events(
@@ -178,6 +193,25 @@ def allowed(event: EventBase) -> EventBase | None:
178193
if filtered is None:
179194
return None
180195

196+
# Filter out call invites in public rooms, as this would potentially
197+
# ring a lot of users.
198+
if event.type == EventTypes.CallInvite and not event.is_state():
199+
# `state_after_event` should only be None if the event is an outlier,
200+
# and earlier code should filter out outliers entirely.
201+
#
202+
# In addition, we only create outliers locally for out-of-band
203+
# invite rejections, invites received over federation, or state
204+
# events needed to authorise other events. None of this applies to
205+
# call invites.
206+
assert state_after_event is not None
207+
208+
room_join_rules = state_after_event.get((EventTypes.JoinRules, ""))
209+
if (
210+
room_join_rules is not None
211+
and room_join_rules.content.get("join_rule") == JoinRules.PUBLIC
212+
):
213+
return None
214+
181215
# Annotate the event with the user's membership after the event.
182216
#
183217
# Normally we just look in `state_after_event`, but if the event is an outlier

0 commit comments

Comments
 (0)