Implement MSC2175: remove the creator field from create events. (#15394)
parent
3ad221ea40
commit
d07d255830
|
@ -0,0 +1 @@
|
||||||
|
Implement [MSC2175](https://github.com/matrix-org/matrix-doc/pull/2175) to stop adding `creator` to create events.
|
|
@ -215,6 +215,8 @@ class EventContentFields:
|
||||||
FEDERATE: Final = "m.federate"
|
FEDERATE: Final = "m.federate"
|
||||||
|
|
||||||
# The creator of the room, as used in `m.room.create` events.
|
# The creator of the room, as used in `m.room.create` events.
|
||||||
|
#
|
||||||
|
# This is deprecated in MSC2175.
|
||||||
ROOM_CREATOR: Final = "creator"
|
ROOM_CREATOR: Final = "creator"
|
||||||
|
|
||||||
# Used in m.room.guest_access events.
|
# Used in m.room.guest_access events.
|
||||||
|
|
|
@ -78,6 +78,8 @@ class RoomVersion:
|
||||||
# MSC2209: Check 'notifications' key while verifying
|
# MSC2209: Check 'notifications' key while verifying
|
||||||
# m.room.power_levels auth rules.
|
# m.room.power_levels auth rules.
|
||||||
limit_notifications_power_levels: bool
|
limit_notifications_power_levels: bool
|
||||||
|
# MSC2175: No longer include the creator in m.room.create events.
|
||||||
|
msc2175_implicit_room_creator: bool
|
||||||
# MSC2174/MSC2176: Apply updated redaction rules algorithm.
|
# MSC2174/MSC2176: Apply updated redaction rules algorithm.
|
||||||
msc2176_redaction_rules: bool
|
msc2176_redaction_rules: bool
|
||||||
# MSC3083: Support the 'restricted' join_rule.
|
# MSC3083: Support the 'restricted' join_rule.
|
||||||
|
@ -118,6 +120,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=True,
|
special_case_aliases_auth=True,
|
||||||
strict_canonicaljson=False,
|
strict_canonicaljson=False,
|
||||||
limit_notifications_power_levels=False,
|
limit_notifications_power_levels=False,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -138,6 +141,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=True,
|
special_case_aliases_auth=True,
|
||||||
strict_canonicaljson=False,
|
strict_canonicaljson=False,
|
||||||
limit_notifications_power_levels=False,
|
limit_notifications_power_levels=False,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -158,6 +162,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=True,
|
special_case_aliases_auth=True,
|
||||||
strict_canonicaljson=False,
|
strict_canonicaljson=False,
|
||||||
limit_notifications_power_levels=False,
|
limit_notifications_power_levels=False,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -178,6 +183,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=True,
|
special_case_aliases_auth=True,
|
||||||
strict_canonicaljson=False,
|
strict_canonicaljson=False,
|
||||||
limit_notifications_power_levels=False,
|
limit_notifications_power_levels=False,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -198,6 +204,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=True,
|
special_case_aliases_auth=True,
|
||||||
strict_canonicaljson=False,
|
strict_canonicaljson=False,
|
||||||
limit_notifications_power_levels=False,
|
limit_notifications_power_levels=False,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -218,6 +225,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -238,6 +246,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=True,
|
msc2176_redaction_rules=True,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -258,6 +267,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -278,6 +288,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -298,6 +309,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=True,
|
msc3375_redaction_rules=True,
|
||||||
|
@ -318,6 +330,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=True,
|
msc3375_redaction_rules=True,
|
||||||
|
@ -338,6 +351,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=True,
|
msc3375_redaction_rules=True,
|
||||||
|
@ -358,6 +372,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=False,
|
msc3083_join_rules=False,
|
||||||
msc3375_redaction_rules=False,
|
msc3375_redaction_rules=False,
|
||||||
|
@ -379,6 +394,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=True,
|
msc3375_redaction_rules=True,
|
||||||
|
@ -399,6 +415,7 @@ class RoomVersions:
|
||||||
special_case_aliases_auth=False,
|
special_case_aliases_auth=False,
|
||||||
strict_canonicaljson=True,
|
strict_canonicaljson=True,
|
||||||
limit_notifications_power_levels=True,
|
limit_notifications_power_levels=True,
|
||||||
|
msc2175_implicit_room_creator=False,
|
||||||
msc2176_redaction_rules=False,
|
msc2176_redaction_rules=False,
|
||||||
msc3083_join_rules=True,
|
msc3083_join_rules=True,
|
||||||
msc3375_redaction_rules=True,
|
msc3375_redaction_rules=True,
|
||||||
|
|
|
@ -455,8 +455,11 @@ def _check_create(event: "EventBase") -> None:
|
||||||
"room appears to have unsupported version %s" % (room_version_prop,),
|
"room appears to have unsupported version %s" % (room_version_prop,),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1.4 If content has no creator field, reject.
|
# 1.4 If content has no creator field, reject if the room version requires it.
|
||||||
if EventContentFields.ROOM_CREATOR not in event.content:
|
if (
|
||||||
|
not event.room_version.msc2175_implicit_room_creator
|
||||||
|
and EventContentFields.ROOM_CREATOR not in event.content
|
||||||
|
):
|
||||||
raise AuthError(403, "Create event lacks a 'creator' property")
|
raise AuthError(403, "Create event lacks a 'creator' property")
|
||||||
|
|
||||||
|
|
||||||
|
@ -491,7 +494,11 @@ def _is_membership_change_allowed(
|
||||||
key = (EventTypes.Create, "")
|
key = (EventTypes.Create, "")
|
||||||
create = auth_events.get(key)
|
create = auth_events.get(key)
|
||||||
if create and event.prev_event_ids()[0] == create.event_id:
|
if create and event.prev_event_ids()[0] == create.event_id:
|
||||||
if create.content["creator"] == event.state_key:
|
if room_version.msc2175_implicit_room_creator:
|
||||||
|
creator = create.sender
|
||||||
|
else:
|
||||||
|
creator = create.content[EventContentFields.ROOM_CREATOR]
|
||||||
|
if creator == event.state_key:
|
||||||
return
|
return
|
||||||
|
|
||||||
target_user_id = event.state_key
|
target_user_id = event.state_key
|
||||||
|
@ -1004,9 +1011,13 @@ def get_user_power_level(user_id: str, auth_events: StateMap["EventBase"]) -> in
|
||||||
# that.
|
# that.
|
||||||
key = (EventTypes.Create, "")
|
key = (EventTypes.Create, "")
|
||||||
create_event = auth_events.get(key)
|
create_event = auth_events.get(key)
|
||||||
if create_event is not None and create_event.content["creator"] == user_id:
|
if create_event is not None:
|
||||||
return 100
|
if create_event.room_version.msc2175_implicit_room_creator:
|
||||||
|
creator = create_event.sender
|
||||||
else:
|
else:
|
||||||
|
creator = create_event.content[EventContentFields.ROOM_CREATOR]
|
||||||
|
if creator == user_id:
|
||||||
|
return 100
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1515,7 +1515,10 @@ class FederationEventHandler:
|
||||||
# support it or the event is not from the room creator.
|
# support it or the event is not from the room creator.
|
||||||
room_version = await self._store.get_room_version(marker_event.room_id)
|
room_version = await self._store.get_room_version(marker_event.room_id)
|
||||||
create_event = await self._store.get_create_event_for_room(marker_event.room_id)
|
create_event = await self._store.get_create_event_for_room(marker_event.room_id)
|
||||||
|
if not room_version.msc2175_implicit_room_creator:
|
||||||
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)
|
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)
|
||||||
|
else:
|
||||||
|
room_creator = create_event.sender
|
||||||
if not room_version.msc2716_historical and (
|
if not room_version.msc2716_historical and (
|
||||||
not self._config.experimental.msc2716_enabled
|
not self._config.experimental.msc2716_enabled
|
||||||
or marker_event.sender != room_creator
|
or marker_event.sender != room_creator
|
||||||
|
|
|
@ -1909,7 +1909,12 @@ class EventCreationHandler:
|
||||||
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
|
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
|
||||||
|
|
||||||
create_event = await self.store.get_create_event_for_room(event.room_id)
|
create_event = await self.store.get_create_event_for_room(event.room_id)
|
||||||
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)
|
if not room_version_obj.msc2175_implicit_room_creator:
|
||||||
|
room_creator = create_event.content.get(
|
||||||
|
EventContentFields.ROOM_CREATOR
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
room_creator = create_event.sender
|
||||||
|
|
||||||
# Only check an insertion event if the room version
|
# Only check an insertion event if the room version
|
||||||
# supports it or the event is from the room creator.
|
# supports it or the event is from the room creator.
|
||||||
|
|
|
@ -567,6 +567,7 @@ class RoomCreationHandler:
|
||||||
await self._send_events_for_new_room(
|
await self._send_events_for_new_room(
|
||||||
requester,
|
requester,
|
||||||
new_room_id,
|
new_room_id,
|
||||||
|
new_room_version,
|
||||||
# we expect to override all the presets with initial_state, so this is
|
# we expect to override all the presets with initial_state, so this is
|
||||||
# somewhat arbitrary.
|
# somewhat arbitrary.
|
||||||
room_config={"preset": RoomCreationPreset.PRIVATE_CHAT},
|
room_config={"preset": RoomCreationPreset.PRIVATE_CHAT},
|
||||||
|
@ -922,6 +923,7 @@ class RoomCreationHandler:
|
||||||
) = await self._send_events_for_new_room(
|
) = await self._send_events_for_new_room(
|
||||||
requester,
|
requester,
|
||||||
room_id,
|
room_id,
|
||||||
|
room_version,
|
||||||
room_config=config,
|
room_config=config,
|
||||||
invite_list=invite_list,
|
invite_list=invite_list,
|
||||||
initial_state=initial_state,
|
initial_state=initial_state,
|
||||||
|
@ -998,6 +1000,7 @@ class RoomCreationHandler:
|
||||||
self,
|
self,
|
||||||
creator: Requester,
|
creator: Requester,
|
||||||
room_id: str,
|
room_id: str,
|
||||||
|
room_version: RoomVersion,
|
||||||
room_config: JsonDict,
|
room_config: JsonDict,
|
||||||
invite_list: List[str],
|
invite_list: List[str],
|
||||||
initial_state: MutableStateMap,
|
initial_state: MutableStateMap,
|
||||||
|
@ -1020,6 +1023,8 @@ class RoomCreationHandler:
|
||||||
the user requesting the room creation
|
the user requesting the room creation
|
||||||
room_id:
|
room_id:
|
||||||
room id for the room being created
|
room id for the room being created
|
||||||
|
room_version:
|
||||||
|
The room version of the new room.
|
||||||
room_config:
|
room_config:
|
||||||
A dict of configuration options. This will be the body of
|
A dict of configuration options. This will be the body of
|
||||||
a /createRoom request; see
|
a /createRoom request; see
|
||||||
|
@ -1053,14 +1058,6 @@ class RoomCreationHandler:
|
||||||
# (as this info can't be pulled from the db)
|
# (as this info can't be pulled from the db)
|
||||||
state_map: MutableStateMap[str] = {}
|
state_map: MutableStateMap[str] = {}
|
||||||
|
|
||||||
def create_event_dict(etype: str, content: JsonDict, **kwargs: Any) -> JsonDict:
|
|
||||||
e = {"type": etype, "content": content}
|
|
||||||
|
|
||||||
e.update(event_keys)
|
|
||||||
e.update(kwargs)
|
|
||||||
|
|
||||||
return e
|
|
||||||
|
|
||||||
async def create_event(
|
async def create_event(
|
||||||
etype: str,
|
etype: str,
|
||||||
content: JsonDict,
|
content: JsonDict,
|
||||||
|
@ -1083,7 +1080,10 @@ class RoomCreationHandler:
|
||||||
nonlocal depth
|
nonlocal depth
|
||||||
nonlocal prev_event
|
nonlocal prev_event
|
||||||
|
|
||||||
event_dict = create_event_dict(etype, content, **kwargs)
|
# Create the event dictionary.
|
||||||
|
event_dict = {"type": etype, "content": content}
|
||||||
|
event_dict.update(event_keys)
|
||||||
|
event_dict.update(kwargs)
|
||||||
|
|
||||||
(
|
(
|
||||||
new_event,
|
new_event,
|
||||||
|
@ -1120,7 +1120,9 @@ class RoomCreationHandler:
|
||||||
400, f"'{preset_config}' is not a valid preset", errcode=Codes.BAD_JSON
|
400, f"'{preset_config}' is not a valid preset", errcode=Codes.BAD_JSON
|
||||||
)
|
)
|
||||||
|
|
||||||
creation_content.update({"creator": creator_id})
|
# MSC2175 removes the creator field from the create event.
|
||||||
|
if not room_version.msc2175_implicit_room_creator:
|
||||||
|
creation_content["creator"] = creator_id
|
||||||
creation_event, unpersisted_creation_context = await create_event(
|
creation_event, unpersisted_creation_context = await create_event(
|
||||||
EventTypes.Create, creation_content, False
|
EventTypes.Create, creation_content, False
|
||||||
)
|
)
|
||||||
|
|
|
@ -1998,6 +1998,9 @@ class RoomBackgroundUpdateStore(SQLBaseStore):
|
||||||
for room_id, event_json in room_id_to_create_event_results:
|
for room_id, event_json in room_id_to_create_event_results:
|
||||||
event_dict = db_to_json(event_json)
|
event_dict = db_to_json(event_json)
|
||||||
|
|
||||||
|
# The creator property might not exist in newer room versions, but
|
||||||
|
# for those versions the creator column should be properly populate
|
||||||
|
# during room creation.
|
||||||
creator = event_dict.get("content").get(EventContentFields.ROOM_CREATOR)
|
creator = event_dict.get("content").get(EventContentFields.ROOM_CREATOR)
|
||||||
|
|
||||||
self.db_pool.simple_update_txn(
|
self.db_pool.simple_update_txn(
|
||||||
|
@ -2132,12 +2135,16 @@ class RoomStore(RoomBackgroundUpdateStore, RoomWorkerStore):
|
||||||
# invalid, and it would fail auth checks anyway.
|
# invalid, and it would fail auth checks anyway.
|
||||||
raise StoreError(400, "No create event in state")
|
raise StoreError(400, "No create event in state")
|
||||||
|
|
||||||
|
# Before MSC2175, the room creator was a separate field.
|
||||||
|
if not room_version.msc2175_implicit_room_creator:
|
||||||
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)
|
room_creator = create_event.content.get(EventContentFields.ROOM_CREATOR)
|
||||||
|
|
||||||
if not isinstance(room_creator, str):
|
if not isinstance(room_creator, str):
|
||||||
# If the create event does not have a creator then the room is
|
# If the create event does not have a creator then the room is
|
||||||
# invalid, and it would fail auth checks anyway.
|
# invalid, and it would fail auth checks anyway.
|
||||||
raise StoreError(400, "No creator defined on the create event")
|
raise StoreError(400, "No creator defined on the create event")
|
||||||
|
else:
|
||||||
|
room_creator = create_event.sender
|
||||||
|
|
||||||
await self.db_pool.simple_upsert(
|
await self.db_pool.simple_upsert(
|
||||||
desc="upsert_room_on_join",
|
desc="upsert_room_on_join",
|
||||||
|
|
Loading…
Reference in New Issue