summary refs log tree commit diff
path: root/synapse/event_auth.py
diff options
context:
space:
mode:
authorAndrew Ferrazzutti <andrewf@element.io>2024-09-26 09:25:05 -0400
committerGitHub <noreply@github.com>2024-09-26 15:25:05 +0200
commit302534c3487b7f3a4be6963d628f919d61bc22a6 (patch)
tree48e8927cd68533beb175c53e23013c26ab1a7b57 /synapse/event_auth.py
parentChangelog fixes (diff)
downloadsynapse-302534c3487b7f3a4be6963d628f919d61bc22a6.tar.xz
Support MSC3757: Restricting who can overwrite a state event (#17513)
Link to the
MSC: https://github.com/matrix-org/matrix-spec-proposals/pull/3757

---------

Co-authored-by: Quentin Gliech <quenting@element.io>
Diffstat (limited to 'synapse/event_auth.py')
-rw-r--r--synapse/event_auth.py37
1 files changed, 31 insertions, 6 deletions
diff --git a/synapse/event_auth.py b/synapse/event_auth.py

index b834547d11..c208b900c5 100644 --- a/synapse/event_auth.py +++ b/synapse/event_auth.py
@@ -388,6 +388,7 @@ LENIENT_EVENT_BYTE_LIMITS_ROOM_VERSIONS = { RoomVersions.V9, RoomVersions.V10, RoomVersions.MSC1767v10, + RoomVersions.MSC3757v10, } @@ -790,9 +791,10 @@ def get_send_level( def _can_send_event(event: "EventBase", auth_events: StateMap["EventBase"]) -> bool: + state_key = event.get_state_key() power_levels_event = get_power_level_event(auth_events) - send_level = get_send_level(event.type, event.get("state_key"), power_levels_event) + send_level = get_send_level(event.type, state_key, power_levels_event) user_level = get_user_power_level(event.user_id, auth_events) if user_level < send_level: @@ -803,11 +805,34 @@ def _can_send_event(event: "EventBase", auth_events: StateMap["EventBase"]) -> b errcode=Codes.INSUFFICIENT_POWER, ) - # Check state_key - if hasattr(event, "state_key"): - if event.state_key.startswith("@"): - if event.state_key != event.user_id: - raise AuthError(403, "You are not allowed to set others state") + if ( + state_key is not None + and state_key.startswith("@") + and state_key != event.user_id + ): + if event.room_version.msc3757_enabled: + try: + colon_idx = state_key.index(":", 1) + suffix_idx = state_key.find("_", colon_idx + 1) + state_key_user_id = ( + state_key[:suffix_idx] if suffix_idx != -1 else state_key + ) + if not UserID.is_valid(state_key_user_id): + raise ValueError + except ValueError: + raise SynapseError( + 400, + "State key neither equals a valid user ID, nor starts with one plus an underscore", + errcode=Codes.BAD_JSON, + ) + if ( + # sender is owner of the state key + state_key_user_id == event.user_id + # sender has higher PL than the owner of the state key + or user_level > get_user_power_level(state_key_user_id, auth_events) + ): + return True + raise AuthError(403, "You are not allowed to set others state") return True