Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/17332.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add implementation of owned state events as proposed by [MSC3779](https://github.com/matrix-org/matrix-spec-proposals/pull/3779).
17 changes: 17 additions & 0 deletions synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ class EventTypes:
CallInvite: Final = "m.call.invite"


ZERO_LENGTH_STATE_KEY_EVENT_TYPES = {
EventTypes.CanonicalAlias,
EventTypes.Create,
EventTypes.JoinRules,
EventTypes.PowerLevels,
EventTypes.Name,
EventTypes.Topic,
EventTypes.RoomAvatar,
EventTypes.Pinned,
EventTypes.RoomEncryption,
EventTypes.RoomHistoryVisibility,
EventTypes.GuestAccess,
EventTypes.ServerACL,
EventTypes.Tombstone,
}


class ToDeviceEventTypes:
RoomKeyRequest: Final = "m.room_key_request"

Expand Down
21 changes: 21 additions & 0 deletions synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,26 @@ class RoomVersions:
enforce_int_power_levels=True,
msc3931_push_features=(PushRuleRoomFlag.EXTENSIBLE_EVENTS,),
)
MSC3779v10 = RoomVersion(
# MSC3779 ("Owned" state events) based on room version "10"
"org.matrix.msc3779.10",
RoomDisposition.UNSTABLE,
EventFormatVersions.ROOM_V4_PLUS,
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=False,
strict_canonicaljson=True,
limit_notifications_power_levels=True,
implicit_room_creator=False,
updated_redaction_rules=False,
restricted_join_rule=True,
restricted_join_rule_fix=True,
knock_join_rule=True,
msc3389_relation_redactions=False,
knock_restricted_join_rule=True,
enforce_int_power_levels=True,
msc3931_push_features=(),
)
V11 = RoomVersion(
"11",
RoomDisposition.STABLE,
Expand Down Expand Up @@ -355,6 +375,7 @@ class RoomVersions:
RoomVersions.V9,
RoomVersions.V10,
RoomVersions.V11,
RoomVersions.MSC3779v10,
)
}

Expand Down
32 changes: 28 additions & 4 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

from synapse.api.constants import (
MAX_PDU_SIZE,
ZERO_LENGTH_STATE_KEY_EVENT_TYPES,
EventContentFields,
EventTypes,
JoinRules,
Expand Down Expand Up @@ -388,6 +389,7 @@ def check_state_dependent_auth_rules(
RoomVersions.V9,
RoomVersions.V10,
RoomVersions.MSC1767v10,
RoomVersions.MSC3779v10,
}


Expand Down Expand Up @@ -753,7 +755,10 @@ def _check_joined_room(


def get_send_level(
etype: str, state_key: Optional[str], power_levels_event: Optional["EventBase"]
etype: str,
state_key: Optional[str],
power_levels_event: Optional["EventBase"],
msc_3779_sender: Optional[str] = None,
) -> int:
"""Get the power level required to send an event of a given type

Expand All @@ -767,6 +772,8 @@ def get_send_level(
a state event.
power_levels_event: power levels event
in force at this point in the room
msc_3779_sender: MXID of the user who sent the event.
Only for rooms with MSC3779 ("owned" state events) applied.
Returns:
power level required to send this event.
"""
Expand All @@ -781,7 +788,16 @@ def get_send_level(

# otherwise, fall back to the state_default/events_default.
if send_level is None:
if state_key is not None:
is_owned_state_event = (
msc_3779_sender is not None
and state_key is not None
and (
state_key == msc_3779_sender
or state_key.startswith(msc_3779_sender + "_")
)
and etype not in ZERO_LENGTH_STATE_KEY_EVENT_TYPES
)
if state_key is not None and not is_owned_state_event:
send_level = power_levels_content.get("state_default", 50)
else:
send_level = power_levels_content.get("events_default", 0)
Expand All @@ -792,7 +808,13 @@ def get_send_level(
def _can_send_event(event: "EventBase", auth_events: StateMap["EventBase"]) -> bool:
power_levels_event = get_power_level_event(auth_events)

send_level = get_send_level(event.type, event.get("state_key"), power_levels_event)
use_msc3779 = event.room_version is RoomVersions.MSC3779v10
send_level = get_send_level(
event.type,
event.get("state_key"),
power_levels_event,
event.user_id if use_msc3779 else None,
)
user_level = get_user_power_level(event.user_id, auth_events)

if user_level < send_level:
Expand All @@ -806,7 +828,9 @@ def _can_send_event(event: "EventBase", auth_events: StateMap["EventBase"]) -> b
# Check state_key
if hasattr(event, "state_key"):
if event.state_key.startswith("@"):
if event.state_key != event.user_id:
if event.state_key != event.user_id and not (
use_msc3779 and event.state_key.startswith(event.user_id + "_")
):
raise AuthError(403, "You are not allowed to set others state")

return True
Expand Down