Skip to content

Commit

Permalink
Strip invite/knock event itself and avoid mutating event unsigned
Browse files Browse the repository at this point in the history
Make sure we don't run into
#14919
(matrix-org/synapse#14919)
  • Loading branch information
MadLittleMods committed Jun 17, 2024
1 parent 079194c commit 3e0f759
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 27 deletions.
18 changes: 18 additions & 0 deletions synapse/events/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,21 @@ def maybe_upsert_event_field(
del container[key]

return upsert_okay


def strip_event(event: EventBase) -> JsonDict:
"""
Used for "stripped state" events which provide a simplified view of the state of a
room intended to help a potential joiner identify the room (relevant when the user
is invited or knocked).
Stripped state events can only have the `sender`, `type`, `state_key` and `content`
properties present.
"""

return {
"type": event.type,
"state_key": event.state_key,
"content": event.content,
"sender": event.sender,
}
14 changes: 8 additions & 6 deletions synapse/handlers/sliding_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@

from synapse.api.constants import AccountDataTypes, Direction, EventTypes, Membership
from synapse.events import EventBase
from synapse.events.utils import strip_event
from synapse.storage.roommember import RoomsForUser
from synapse.types import (
JsonDict,
PersistedEventPosition,
Requester,
RoomStreamToken,
Expand Down Expand Up @@ -793,7 +795,7 @@ async def get_room_sync_data(
)

# Figure out any stripped state events for invite/knocks
stripped_state: List[EventBase] = []
stripped_state: List[JsonDict] = []
if rooms_for_user_membership_at_to_token.membership in {
Membership.INVITE,
Membership.KNOCK,
Expand All @@ -804,15 +806,15 @@ async def get_room_sync_data(

stripped_state = []
if invite_or_knock_event.membership == Membership.INVITE:
stripped_state = invite_or_knock_event.unsigned.get(
"invite_room_state", []
stripped_state.extend(
invite_or_knock_event.unsigned.get("invite_room_state", [])
)
elif invite_or_knock_event.membership == Membership.KNOCK:
stripped_state = invite_or_knock_event.unsigned.get(
"knock_room_state", []
stripped_state.extend(
invite_or_knock_event.unsigned.get("knock_room_state", [])
)

stripped_state.append(invite_or_knock_event)
stripped_state.append(strip_event(invite_or_knock_event))

return SlidingSyncResult.RoomResult(
# TODO: Dummy value
Expand Down
10 changes: 1 addition & 9 deletions synapse/rest/client/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,18 +1017,10 @@ async def encode_rooms(

# Stripped state only applies to invite/knock rooms
if room_result.stripped_state:
serialized_stripped_state = (
await self.event_serializer.serialize_events(
room_result.stripped_state,
time_now,
config=serialize_options,
)
)

# TODO: Would be good to rename this to `stripped_state` so it can be
# shared between invite and knock rooms, see
# https://github.com/matrix-org/matrix-spec-proposals/pull/3575#discussion_r1117629919
serialized_rooms[room_id]["invite_state"] = serialized_stripped_state
serialized_rooms[room_id]["invite_state"] = room_result.stripped_state

return serialized_rooms

Expand Down
12 changes: 2 additions & 10 deletions synapse/storage/databases/main/events_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
)
from synapse.events import EventBase, make_event_from_dict
from synapse.events.snapshot import EventContext
from synapse.events.utils import prune_event
from synapse.events.utils import prune_event, strip_event
from synapse.logging.context import (
PreserveLoggingContext,
current_context,
Expand Down Expand Up @@ -1025,15 +1025,7 @@ async def get_stripped_room_state_from_event_context(

state_to_include = await self.get_events(selected_state_ids.values())

return [
{
"type": e.type,
"state_key": e.state_key,
"content": e.content,
"sender": e.sender,
}
for e in state_to_include.values()
]
return [strip_event(e) for e in state_to_include.values()]

def _maybe_start_fetch_thread(self) -> None:
"""Starts an event fetch thread if we are not yet at the maximum number."""
Expand Down
4 changes: 2 additions & 2 deletions synapse/types/handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from pydantic import Extra

from synapse.events import EventBase
from synapse.types import JsonMapping, StreamToken, UserID
from synapse.types import JsonDict, JsonMapping, StreamToken, UserID
from synapse.types.rest.client import SlidingSyncBody


Expand Down Expand Up @@ -193,7 +193,7 @@ class RoomResult:
required_state: List[EventBase]
timeline: List[EventBase]
is_dm: bool
stripped_state: Optional[List[EventBase]]
stripped_state: Optional[List[JsonDict]]
prev_batch: StreamToken
limited: bool
joined_count: int
Expand Down

0 comments on commit 3e0f759

Please sign in to comment.