summary refs log tree commit diff
path: root/synapse/visibility.py
diff options
context:
space:
mode:
authorRichard van der Hoff <1389908+richvdh@users.noreply.github.com>2022-06-01 12:29:51 +0100
committerGitHub <noreply@github.com>2022-06-01 11:29:51 +0000
commit79dadf7216836170af2ac5ef130bfc012b86821c (patch)
tree1a2d9eebc01653db9347581f537df12b28fb427d /synapse/visibility.py
parentFix potential thumbnail memory leaks. (#12932) (diff)
downloadsynapse-79dadf7216836170af2ac5ef130bfc012b86821c.tar.xz
Fix 404 on `/sync` when the last event is a redaction of an unknown/purged event (#12905)
Currently, we try to pull the event corresponding to a sync token from the database. However, when
we fetch redaction events, we check the target of that redaction (because we aren't allowed to send
redactions to clients without validating them). So, if the sync token points to a redaction of an event
that we don't have, we have a problem.

It turns out we don't really need that event, and can just work with its ID and metadata, which
sidesteps the whole problem.
Diffstat (limited to 'synapse/visibility.py')
-rw-r--r--synapse/visibility.py28
1 files changed, 18 insertions, 10 deletions
diff --git a/synapse/visibility.py b/synapse/visibility.py
index 97548c14e3..8aaa8c709f 100644
--- a/synapse/visibility.py
+++ b/synapse/visibility.py
@@ -162,16 +162,7 @@ async def filter_events_for_client(
         state = event_id_to_state[event.event_id]
 
         # get the room_visibility at the time of the event.
-        visibility_event = state.get(_HISTORY_VIS_KEY, None)
-        if visibility_event:
-            visibility = visibility_event.content.get(
-                "history_visibility", HistoryVisibility.SHARED
-            )
-        else:
-            visibility = HistoryVisibility.SHARED
-
-        if visibility not in VISIBILITY_PRIORITY:
-            visibility = HistoryVisibility.SHARED
+        visibility = get_effective_room_visibility_from_state(state)
 
         # Always allow history visibility events on boundaries. This is done
         # by setting the effective visibility to the least restrictive
@@ -267,6 +258,23 @@ async def filter_events_for_client(
     return [ev for ev in filtered_events if ev]
 
 
+def get_effective_room_visibility_from_state(state: StateMap[EventBase]) -> str:
+    """Get the actual history vis, from a state map including the history_visibility event
+
+    Handles missing and invalid history visibility events.
+    """
+    visibility_event = state.get(_HISTORY_VIS_KEY, None)
+    if not visibility_event:
+        return HistoryVisibility.SHARED
+
+    visibility = visibility_event.content.get(
+        "history_visibility", HistoryVisibility.SHARED
+    )
+    if visibility not in VISIBILITY_PRIORITY:
+        visibility = HistoryVisibility.SHARED
+    return visibility
+
+
 async def filter_events_for_server(
     storage: StorageControllers,
     server_name: str,