Skip to content

Commit a6c349e

Browse files
committed
Add create_config helper
Rather than implicitly updating the config in `serialize_event`, let's add a helper for creating the config that does the necessary checks/updates itself.
1 parent 3254557 commit a6c349e

16 files changed

Lines changed: 120 additions & 136 deletions

File tree

rust/src/events/serialize.rs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,6 @@ pub struct SerializeEventConfig {
130130
impl SerializeEventConfig {
131131
#[new]
132132
#[allow(clippy::too_many_arguments)]
133-
#[pyo3(signature = (
134-
*,
135-
as_client_event = true,
136-
event_format = EventFormat::ClientV1,
137-
requester = None,
138-
event_field_allowlist = None,
139-
include_stripped_room_state = false,
140-
include_admin_metadata = false,
141-
msc4354_enabled = false,
142-
))]
143133
fn new(
144134
as_client_event: bool,
145135
event_format: EventFormat,
@@ -199,23 +189,6 @@ impl SerializeEventConfig {
199189
fn msc4354_enabled(&self) -> bool {
200190
self.msc4354_enabled
201191
}
202-
203-
/// Returns a copy of this config with `include_admin_metadata` enabled.
204-
fn for_admin(&self) -> Self {
205-
Self {
206-
include_admin_metadata: true,
207-
..self.clone()
208-
}
209-
}
210-
211-
/// Returns a copy of this config with `msc4354_enabled` set as given.
212-
#[pyo3(signature = (enabled = true))]
213-
fn with_msc4354(&self, enabled: bool) -> Self {
214-
Self {
215-
msc4354_enabled: enabled,
216-
..self.clone()
217-
}
218-
}
219192
}
220193

221194
/// Synchronously serialize a batch of events for clients.

synapse/appservice/api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
TransactionUnusedFallbackKeys,
4141
)
4242
from synapse.events import EventBase
43-
from synapse.events.utils import FilteredEvent, SerializeEventConfig
43+
from synapse.events.utils import FilteredEvent
4444
from synapse.http.client import SimpleHttpClient, is_unknown_endpoint
4545
from synapse.logging import opentracing
4646
from synapse.metrics import SERVER_NAME_LABEL
@@ -547,7 +547,7 @@ async def _serialize(
547547
return await self._event_serializer.serialize_events(
548548
[FilteredEvent(event=e, membership=None) for e in events],
549549
time_now,
550-
config=SerializeEventConfig(
550+
config=await self._event_serializer.create_config(
551551
as_client_event=True,
552552
# If this is an invite or a knock membership event, then include
553553
# any stripped state alongside the event. We could narrow this

synapse/events/utils.py

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
redact_event,
4949
serialize_events,
5050
)
51+
from synapse.synapse_rust.types import Requester
5152
from synapse.types import JsonDict
5253

5354
from . import EventBase, StrippedStateEvent
@@ -135,15 +136,6 @@ def admin_override(cls, event: "EventBase") -> "FilteredEvent":
135136
return cls(event=event, membership=None)
136137

137138

138-
_DEFAULT_SERIALIZE_EVENT_CONFIG = SerializeEventConfig()
139-
140-
141-
def make_config_for_admin(existing: SerializeEventConfig) -> SerializeEventConfig:
142-
# Thin wrapper kept for callers; see SerializeEventConfig.for_admin for the
143-
# admin-only options it sets.
144-
return existing.for_admin()
145-
146-
147139
class EventClientSerializer:
148140
"""Serializes events that are to be sent to clients.
149141
@@ -160,12 +152,65 @@ def __init__(self, hs: "HomeServer") -> None:
160152
ADD_EXTRA_FIELDS_TO_UNSIGNED_CLIENT_EVENT_CALLBACK
161153
] = []
162154

155+
async def create_config(
156+
self,
157+
*,
158+
as_client_event: bool = True,
159+
event_format: EventFormat = EventFormat.ClientV1,
160+
requester: Requester | None = None,
161+
event_field_allowlist: list[str] | None = None,
162+
include_stripped_room_state: bool = False,
163+
include_admin_metadata: bool | None = None,
164+
) -> SerializeEventConfig:
165+
"""
166+
Create a new SerializeEventConfig for the given parameters.
167+
168+
Helper method that sets the `include_admin_metadata` field based on
169+
whether the requester is a server admin if it is not explicitly
170+
provided. Also sets the `msc4354_enabled` field based on the homeserver
171+
config.
172+
173+
Args:
174+
as_client_event: Whether to serialize the events as client events.
175+
event_format: The format to serialize events in. requester: The user
176+
requesting the events, if any. Used to determine
177+
whether to include admin-only metadata in the serialized events.
178+
event_field_allowlist: A list of event fields to include in the
179+
serialized events.
180+
include_stripped_room_state: Whether to include stripped room state
181+
in the serialized events.
182+
include_admin_metadata: Whether to include admin-only metadata in
183+
the serialized events. If None, this will be determined based on
184+
whether the requester is a server admin.
185+
Returns:
186+
A SerializeEventConfig instance.
187+
"""
188+
189+
# If include_admin_metadata is None, determine whether to include
190+
# admin-only metadata based on the requester.
191+
if include_admin_metadata is None:
192+
# Check if the requester is a server admin.
193+
if requester is not None and await self._auth.is_server_admin(requester):
194+
include_admin_metadata = True
195+
else:
196+
include_admin_metadata = False
197+
198+
return SerializeEventConfig(
199+
as_client_event=as_client_event,
200+
event_format=event_format,
201+
requester=requester,
202+
event_field_allowlist=event_field_allowlist,
203+
include_stripped_room_state=include_stripped_room_state,
204+
include_admin_metadata=include_admin_metadata,
205+
msc4354_enabled=self._config.experimental.msc4354_enabled,
206+
)
207+
163208
async def serialize_event(
164209
self,
165210
event: JsonDict | FilteredEvent,
166211
time_now: int,
167212
*,
168-
config: SerializeEventConfig = _DEFAULT_SERIALIZE_EVENT_CONFIG,
213+
config: SerializeEventConfig | None = None,
169214
bundle_aggregations: dict[str, "BundledAggregations"] | None = None,
170215
redaction_map: Mapping[str, "EventBase"] | None = None,
171216
) -> JsonDict:
@@ -187,7 +232,9 @@ async def serialize_event(
187232
if not isinstance(event, FilteredEvent):
188233
return event
189234

190-
config = await self._update_config(config)
235+
if config is None:
236+
# Generate default config if none was provided.
237+
config = await self.create_config()
191238

192239
# Perform all the async DB/IO work up front, then run the synchronous
193240
# serialization core.
@@ -204,28 +251,6 @@ async def serialize_event(
204251
unsigned_additions=unsigned_additions,
205252
)[0]
206253

207-
async def _update_config(
208-
self, config: SerializeEventConfig
209-
) -> SerializeEventConfig:
210-
"""Update the config based on the requester and server config."""
211-
212-
# Force-enable server admin metadata because the only time an event with
213-
# relevant metadata will be when the admin requested it via their admin
214-
# client config account data. Also, it's "just" some `unsigned` fields, so
215-
# shouldn't cause much in terms of problems to downstream consumers.
216-
#
217-
# The requester is constant across the whole (recursive) serialization,
218-
# so we only need to resolve this once.
219-
if config.requester is not None and await self._auth.is_server_admin(
220-
config.requester
221-
):
222-
config = make_config_for_admin(config)
223-
224-
if self._config.experimental.msc4354_enabled:
225-
config = config.with_msc4354(True)
226-
227-
return config
228-
229254
async def _prepare_serialization(
230255
self,
231256
events: Collection[FilteredEvent],
@@ -313,7 +338,7 @@ async def serialize_events(
313338
events: Collection[JsonDict | FilteredEvent],
314339
time_now: int,
315340
*,
316-
config: SerializeEventConfig = _DEFAULT_SERIALIZE_EVENT_CONFIG,
341+
config: SerializeEventConfig | None = None,
317342
bundle_aggregations: dict[str, "BundledAggregations"] | None = None,
318343
) -> list[JsonDict]:
319344
"""Serializes multiple events.
@@ -334,7 +359,9 @@ async def serialize_events(
334359
str(len(events)),
335360
)
336361

337-
config = await self._update_config(config)
362+
if config is None:
363+
# Generate default config if none was provided.
364+
config = await self.create_config()
338365

339366
filtered_events = [e for e in events if isinstance(e, FilteredEvent)]
340367

synapse/handlers/events.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from synapse.api.constants import EduTypes, EventTypes, Membership, PresenceState
2727
from synapse.api.errors import AuthError, SynapseError
28-
from synapse.events.utils import FilteredEvent, SerializeEventConfig
28+
from synapse.events.utils import FilteredEvent
2929
from synapse.handlers.presence import format_user_presence_state
3030
from synapse.storage.databases.main.events_worker import EventRedactBehaviour
3131
from synapse.streams.config import PaginationConfig
@@ -129,7 +129,7 @@ async def get_stream(
129129
chunks = await self._event_serializer.serialize_events(
130130
events,
131131
time_now,
132-
config=SerializeEventConfig(
132+
config=await self._event_serializer.create_config(
133133
as_client_event=as_client_event, requester=requester
134134
),
135135
)

synapse/handlers/initial_sync.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
Membership,
3131
)
3232
from synapse.api.errors import SynapseError
33-
from synapse.events.utils import FilteredEvent, SerializeEventConfig
33+
from synapse.events.utils import FilteredEvent
3434
from synapse.events.validator import EventValidator
3535
from synapse.handlers.presence import format_user_presence_state
3636
from synapse.handlers.receipts import ReceiptEventSource
@@ -169,7 +169,9 @@ async def _snapshot_all_rooms(
169169

170170
public_room_ids = await self.store.get_public_room_ids()
171171

172-
serializer_options = SerializeEventConfig(as_client_event=as_client_event)
172+
serializer_options = await self._event_serializer.create_config(
173+
as_client_event=as_client_event
174+
)
173175

174176
async def handle_room(event: RoomsForUser) -> None:
175177
d: JsonDict = {
@@ -395,7 +397,9 @@ async def _room_initial_sync_parted(
395397
end_token = StreamToken.START.copy_and_replace(StreamKeyType.ROOM, stream_token)
396398

397399
time_now = self.clock.time_msec()
398-
serialize_options = SerializeEventConfig(requester=requester)
400+
serialize_options = await self._event_serializer.create_config(
401+
requester=requester
402+
)
399403

400404
return {
401405
"membership": membership,
@@ -436,7 +440,9 @@ async def _room_initial_sync_joined(
436440

437441
# TODO: These concurrently
438442
time_now = self.clock.time_msec()
439-
serialize_options = SerializeEventConfig(requester=requester)
443+
serialize_options = await self._event_serializer.create_config(
444+
requester=requester
445+
)
440446
# Don't bundle aggregations as this is a deprecated API.
441447
state = await self._event_serializer.serialize_events(
442448
[FilteredEvent.state(e) for e in current_state.values()],

synapse/handlers/message.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
)
6565
from synapse.events.utils import (
6666
FilteredEvent,
67-
SerializeEventConfig,
6867
maybe_upsert_event_field,
6968
)
7069
from synapse.events.validator import EventValidator
@@ -269,7 +268,7 @@ async def get_state_events(
269268
events = await self._event_serializer.serialize_events(
270269
[FilteredEvent.state(e) for e in room_state.values()],
271270
self.clock.time_msec(),
272-
config=SerializeEventConfig(requester=requester),
271+
config=await self._event_serializer.create_config(requester=requester),
273272
)
274273
return events
275274

synapse/handlers/relations.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from synapse.api.constants import Direction, EventTypes, RelationTypes
3232
from synapse.api.errors import SynapseError
3333
from synapse.events import EventBase, relation_from_event
34-
from synapse.events.utils import FilteredEvent, SerializeEventConfig
34+
from synapse.events.utils import FilteredEvent
3535
from synapse.logging.context import make_deferred_yieldable, run_in_background
3636
from synapse.logging.opentracing import trace
3737
from synapse.storage.databases.main.relations import ThreadsNextBatch, _RelatedEvent
@@ -150,7 +150,9 @@ async def get_relations(
150150
)
151151

152152
now = self._clock.time_msec()
153-
serialize_options = SerializeEventConfig(requester=requester)
153+
serialize_options = await self._event_serializer.create_config(
154+
requester=requester
155+
)
154156
return_value: JsonDict = {
155157
"chunk": await self._event_serializer.serialize_events(
156158
filtered_events,

synapse/handlers/search.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from synapse.api.constants import EventTypes, Membership
3030
from synapse.api.errors import NotFoundError, SynapseError
3131
from synapse.api.filtering import Filter
32-
from synapse.events.utils import FilteredEvent, SerializeEventConfig
32+
from synapse.events.utils import FilteredEvent
3333
from synapse.types import JsonDict, Requester, StrCollection, StreamKeyType, UserID
3434
from synapse.types.state import StateFilter
3535
from synapse.visibility import filter_and_transform_events_for_client
@@ -377,7 +377,9 @@ async def _search(
377377
# blocking calls after this. Otherwise, the 'age' will be wrong.
378378

379379
time_now = self.clock.time_msec()
380-
serialize_options = SerializeEventConfig(requester=requester)
380+
serialize_options = await self._event_serializer.create_config(
381+
requester=requester
382+
)
381383

382384
for context in contexts.values():
383385
context["events_before"] = await self._event_serializer.serialize_events(

synapse/rest/admin/events.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from synapse.events.utils import (
66
EventFormat,
77
FilteredEvent,
8-
SerializeEventConfig,
98
)
109
from synapse.http.servlet import RestServlet
1110
from synapse.http.site import SynapseRequest
@@ -57,7 +56,7 @@ async def on_GET(
5756
if event is None:
5857
raise NotFoundError("Event not found")
5958

60-
config = SerializeEventConfig(
59+
config = await self._event_serializer.create_config(
6160
as_client_event=False,
6261
event_format=EventFormat.Raw,
6362
requester=requester,

synapse/rest/admin/rooms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ async def on_GET(
10281028
):
10291029
as_client_event = False
10301030

1031-
serialize_options = SerializeEventConfig(
1031+
serialize_options = await self._event_serializer.create_config(
10321032
as_client_event=as_client_event, requester=requester
10331033
)
10341034

0 commit comments

Comments
 (0)