Skip to content

Commit 887bb56

Browse files
committed
MSC4291 dev
1 parent 481c4e2 commit 887bb56

File tree

16 files changed

+520
-74
lines changed

16 files changed

+520
-74
lines changed

Cargo.lock

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

changelog.d/18685.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for MSC4291: Room IDs as hashes of create event.

synapse/api/room_versions.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ class EventFormatVersions:
3636
ROOM_V1_V2 = 1 # $id:server event id format: used for room v1 and v2
3737
ROOM_V3 = 2 # MSC1659-style $hash event id format: used for room v3
3838
ROOM_V4_PLUS = 3 # MSC1884-style $hash format: introduced for room v4
39+
ROOM_V11_PLUS_MSC4291 = 4 # MSC4291 room IDs as hashes: introduced for room MSC4291v11
3940

4041

4142
KNOWN_EVENT_FORMAT_VERSIONS = {
4243
EventFormatVersions.ROOM_V1_V2,
4344
EventFormatVersions.ROOM_V3,
4445
EventFormatVersions.ROOM_V4_PLUS,
46+
EventFormatVersions.ROOM_V11_PLUS_MSC4291,
4547
}
4648

4749

@@ -109,6 +111,8 @@ class RoomVersion:
109111
msc3931_push_features: Tuple[str, ...] # values from PushRuleRoomFlag
110112
# MSC3757: Restricting who can overwrite a state event
111113
msc3757_enabled: bool
114+
# MSC4291: Room IDs as hashes of the create event
115+
msc4291_room_ids_as_hashes: bool
112116

113117

114118
class RoomVersions:
@@ -131,6 +135,7 @@ class RoomVersions:
131135
enforce_int_power_levels=False,
132136
msc3931_push_features=(),
133137
msc3757_enabled=False,
138+
msc4291_room_ids_as_hashes=False,
134139
)
135140
V2 = RoomVersion(
136141
"2",
@@ -151,6 +156,7 @@ class RoomVersions:
151156
enforce_int_power_levels=False,
152157
msc3931_push_features=(),
153158
msc3757_enabled=False,
159+
msc4291_room_ids_as_hashes=False,
154160
)
155161
V3 = RoomVersion(
156162
"3",
@@ -171,6 +177,7 @@ class RoomVersions:
171177
enforce_int_power_levels=False,
172178
msc3931_push_features=(),
173179
msc3757_enabled=False,
180+
msc4291_room_ids_as_hashes=False,
174181
)
175182
V4 = RoomVersion(
176183
"4",
@@ -191,6 +198,7 @@ class RoomVersions:
191198
enforce_int_power_levels=False,
192199
msc3931_push_features=(),
193200
msc3757_enabled=False,
201+
msc4291_room_ids_as_hashes=False,
194202
)
195203
V5 = RoomVersion(
196204
"5",
@@ -211,6 +219,7 @@ class RoomVersions:
211219
enforce_int_power_levels=False,
212220
msc3931_push_features=(),
213221
msc3757_enabled=False,
222+
msc4291_room_ids_as_hashes=False,
214223
)
215224
V6 = RoomVersion(
216225
"6",
@@ -231,6 +240,7 @@ class RoomVersions:
231240
enforce_int_power_levels=False,
232241
msc3931_push_features=(),
233242
msc3757_enabled=False,
243+
msc4291_room_ids_as_hashes=False,
234244
)
235245
V7 = RoomVersion(
236246
"7",
@@ -251,6 +261,7 @@ class RoomVersions:
251261
enforce_int_power_levels=False,
252262
msc3931_push_features=(),
253263
msc3757_enabled=False,
264+
msc4291_room_ids_as_hashes=False,
254265
)
255266
V8 = RoomVersion(
256267
"8",
@@ -271,6 +282,7 @@ class RoomVersions:
271282
enforce_int_power_levels=False,
272283
msc3931_push_features=(),
273284
msc3757_enabled=False,
285+
msc4291_room_ids_as_hashes=False,
274286
)
275287
V9 = RoomVersion(
276288
"9",
@@ -291,6 +303,7 @@ class RoomVersions:
291303
enforce_int_power_levels=False,
292304
msc3931_push_features=(),
293305
msc3757_enabled=False,
306+
msc4291_room_ids_as_hashes=False,
294307
)
295308
V10 = RoomVersion(
296309
"10",
@@ -311,6 +324,7 @@ class RoomVersions:
311324
enforce_int_power_levels=True,
312325
msc3931_push_features=(),
313326
msc3757_enabled=False,
327+
msc4291_room_ids_as_hashes=False,
314328
)
315329
MSC1767v10 = RoomVersion(
316330
# MSC1767 (Extensible Events) based on room version "10"
@@ -332,6 +346,7 @@ class RoomVersions:
332346
enforce_int_power_levels=True,
333347
msc3931_push_features=(PushRuleRoomFlag.EXTENSIBLE_EVENTS,),
334348
msc3757_enabled=False,
349+
msc4291_room_ids_as_hashes=False,
335350
)
336351
MSC3757v10 = RoomVersion(
337352
# MSC3757 (Restricting who can overwrite a state event) based on room version "10"
@@ -353,6 +368,7 @@ class RoomVersions:
353368
enforce_int_power_levels=True,
354369
msc3931_push_features=(),
355370
msc3757_enabled=True,
371+
msc4291_room_ids_as_hashes=False,
356372
)
357373
V11 = RoomVersion(
358374
"11",
@@ -373,6 +389,7 @@ class RoomVersions:
373389
enforce_int_power_levels=True,
374390
msc3931_push_features=(),
375391
msc3757_enabled=False,
392+
msc4291_room_ids_as_hashes=False,
376393
)
377394
MSC3757v11 = RoomVersion(
378395
# MSC3757 (Restricting who can overwrite a state event) based on room version "11"
@@ -394,6 +411,28 @@ class RoomVersions:
394411
enforce_int_power_levels=True,
395412
msc3931_push_features=(),
396413
msc3757_enabled=True,
414+
msc4291_room_ids_as_hashes=False,
415+
)
416+
MSC4291v11 = RoomVersion(
417+
"org.matrix.msc4291.11",
418+
RoomDisposition.UNSTABLE,
419+
EventFormatVersions.ROOM_V11_PLUS_MSC4291,
420+
StateResolutionVersions.V2,
421+
enforce_key_validity=True,
422+
special_case_aliases_auth=False,
423+
strict_canonicaljson=True,
424+
limit_notifications_power_levels=True,
425+
implicit_room_creator=True, # Used by MSC3820
426+
updated_redaction_rules=True, # Used by MSC3820
427+
restricted_join_rule=True,
428+
restricted_join_rule_fix=True,
429+
knock_join_rule=True,
430+
msc3389_relation_redactions=False,
431+
knock_restricted_join_rule=True,
432+
enforce_int_power_levels=True,
433+
msc3931_push_features=(),
434+
msc3757_enabled=False,
435+
msc4291_room_ids_as_hashes=True,
397436
)
398437

399438

@@ -413,6 +452,7 @@ class RoomVersions:
413452
RoomVersions.V11,
414453
RoomVersions.MSC3757v10,
415454
RoomVersions.MSC3757v11,
455+
RoomVersions.MSC4291v11,
416456
)
417457
}
418458

synapse/crypto/event_signing.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ def compute_content_hash(
101101
event_dict.pop("outlier", None)
102102
event_dict.pop("destinations", None)
103103

104+
# N.B. no need to pop the room_id from create events in MSC4291 rooms
105+
# as they shouldn't have one.
106+
104107
event_json_bytes = encode_canonical_json(event_dict)
105108

106109
hashed = hash_algorithm(event_json_bytes)

synapse/event_auth.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ async def check_state_independent_auth_rules(
261261
f"Event {event.event_id} has unexpected auth_event for {k}: {auth_event_id}",
262262
)
263263

264-
# We also need to check that the auth event itself is not rejected.
264+
# 2.3 ... If there are entries which were themselves rejected under the checks performed on receipt
265+
# of a PDU, reject.
265266
if auth_event.rejected_reason:
266267
raise AuthError(
267268
403,
@@ -271,7 +272,7 @@ async def check_state_independent_auth_rules(
271272

272273
auth_dict[k] = auth_event_id
273274

274-
# 3. If event does not have a m.room.create in its auth_events, reject.
275+
# 2.4. If event does not have a m.room.create in its auth_events, reject.
275276
creation_event = auth_dict.get((EventTypes.Create, ""), None)
276277
if not creation_event:
277278
raise AuthError(403, "No create event in auth events")
@@ -311,13 +312,14 @@ def check_state_dependent_auth_rules(
311312

312313
# Later code relies on there being a create event e.g _can_federate, _is_membership_change_allowed
313314
# so produce a more intelligible error if we don't have one.
314-
if auth_dict.get(CREATE_KEY) is None:
315+
create_event = auth_dict.get(CREATE_KEY)
316+
if create_event is None:
315317
raise AuthError(
316318
403, f"Event {event.event_id} is missing a create event in auth_events."
317319
)
318320

319321
# additional check for m.federate
320-
creating_domain = get_domain_from_id(event.room_id)
322+
creating_domain = get_domain_from_id(create_event.sender)
321323
originating_domain = get_domain_from_id(event.sender)
322324
if creating_domain != originating_domain:
323325
if not _can_federate(event, auth_dict):
@@ -470,12 +472,20 @@ def _check_create(event: "EventBase") -> None:
470472
if event.prev_event_ids():
471473
raise AuthError(403, "Create event has prev events")
472474

473-
# 1.2 If the domain of the room_id does not match the domain of the sender,
474-
# reject.
475-
sender_domain = get_domain_from_id(event.sender)
476-
room_id_domain = get_domain_from_id(event.room_id)
477-
if room_id_domain != sender_domain:
478-
raise AuthError(403, "Creation event's room_id domain does not match sender's")
475+
if event.room_version.msc4291_room_ids_as_hashes:
476+
# 1.2 If the create event has a room_id, reject
477+
if "room_id" in event:
478+
raise AuthError(403, "Create event has a room_id")
479+
else:
480+
# 1.2 If the domain of the room_id does not match the domain of the sender,
481+
# reject.
482+
if not event.room_version.msc4291_room_ids_as_hashes:
483+
sender_domain = get_domain_from_id(event.sender)
484+
room_id_domain = get_domain_from_id(event.room_id)
485+
if room_id_domain != sender_domain:
486+
raise AuthError(
487+
403, "Creation event's room_id domain does not match sender's"
488+
)
479489

480490
# 1.3 If content.room_version is present and is not a recognised version, reject
481491
room_version_prop = event.content.get("room_version", "1")
@@ -533,7 +543,13 @@ def _is_membership_change_allowed(
533543

534544
target_user_id = event.state_key
535545

536-
creating_domain = get_domain_from_id(event.room_id)
546+
# We need the create event in order to check if we can federate or not.
547+
# If it's missing, yell loudly. Previously we only did this inside the
548+
# _can_federate check.
549+
create_event = auth_events.get((EventTypes.Create, ""))
550+
if not create_event:
551+
raise AuthError(403, "Create event missing from auth_events")
552+
creating_domain = get_domain_from_id(create_event.sender)
537553
target_domain = get_domain_from_id(target_user_id)
538554
if creating_domain != target_domain:
539555
if not _can_federate(event, auth_events):

0 commit comments

Comments
 (0)