Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add support for room version 10 #13220

Merged
merged 9 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from 6 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/13220.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for room version 10.
33 changes: 33 additions & 0 deletions synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class RoomVersion:
# MSC3787: Adds support for a `knock_restricted` join rule, mixing concepts of
# knocks and restricted join rules into the same join condition.
msc3787_knock_restricted_join_rule: bool
# MSC3667: Enforce integer power levels
msc3667_int_only_power_levels: bool


class RoomVersions:
Expand All @@ -103,6 +105,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V2 = RoomVersion(
"2",
Expand All @@ -120,6 +123,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V3 = RoomVersion(
"3",
Expand All @@ -137,6 +141,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V4 = RoomVersion(
"4",
Expand All @@ -154,6 +159,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V5 = RoomVersion(
"5",
Expand All @@ -171,6 +177,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V6 = RoomVersion(
"6",
Expand All @@ -188,6 +195,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
MSC2176 = RoomVersion(
"org.matrix.msc2176",
Expand All @@ -205,6 +213,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V7 = RoomVersion(
"7",
Expand All @@ -222,6 +231,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V8 = RoomVersion(
"8",
Expand All @@ -239,6 +249,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
V9 = RoomVersion(
"9",
Expand All @@ -256,6 +267,7 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
MSC2716v3 = RoomVersion(
"org.matrix.msc2716v3",
Expand All @@ -273,6 +285,7 @@ class RoomVersions:
msc2716_historical=True,
msc2716_redactions=True,
msc3787_knock_restricted_join_rule=False,
msc3667_int_only_power_levels=False,
)
MSC3787 = RoomVersion(
"org.matrix.msc3787",
Expand All @@ -290,6 +303,25 @@ class RoomVersions:
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=False,
)
V10 = RoomVersion(
"10",
RoomDisposition.STABLE,
EventFormatVersions.V3,
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=False,
strict_canonicaljson=True,
limit_notifications_power_levels=True,
msc2176_redaction_rules=False,
msc3083_join_rules=True,
msc3375_redaction_rules=True,
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=True,
msc3667_int_only_power_levels=True,
)


Expand All @@ -308,6 +340,7 @@ class RoomVersions:
RoomVersions.V9,
RoomVersions.MSC2716v3,
RoomVersions.MSC3787,
RoomVersions.V10,
)
}

Expand Down
31 changes: 26 additions & 5 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ def validate_event_for_room_version(event: "EventBase") -> None:
Raises:
SynapseError if there is a problem with the event
"""

squahtx marked this conversation as resolved.
Show resolved Hide resolved
_check_size_limits(event)

if not hasattr(event, "room_id"):
Expand Down Expand Up @@ -729,16 +730,36 @@ def _check_power_levels(
) -> None:
user_list = event.content.get("users", {})
# Validate users
for k, v in user_list.items():
for k in user_list.keys():
try:
UserID.from_string(k)
except Exception:
raise SynapseError(400, "Not a valid user_id: %s" % (k,))

try:
int(v)
except Exception:
raise SynapseError(400, "Not a valid power level: %s" % (v,))
squahtx marked this conversation as resolved.
Show resolved Hide resolved
# Reject events with stringy power levels if required by room version
if (
event.type == EventTypes.PowerLevels
and room_version_obj.msc3667_int_only_power_levels
):
for k, v in event.content.items():
if k in {
"users_default",
"events_default",
"state_default",
"ban",
"redact",
"kick",
"invite",
}:
if not isinstance(v, int):
raise AuthError(403, f"{v} must be an integer.")
squahtx marked this conversation as resolved.
Show resolved Hide resolved
if k in {"events", "notifications", "users"}:
if not isinstance(v, dict) or not all(
isinstance(v, int) for v in v.values()
):
raise AuthError(
403, f"{v} must be a dict wherein all the values are integers."
)

key = (event.type, event.state_key)
current_state = auth_events.get(key)
Expand Down
39 changes: 39 additions & 0 deletions tests/test_event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,45 @@ def test_join_rules_msc3083_restricted(self) -> None:
auth_events.values(),
)

def test_room_v10_rejects_string_power_levels(self) -> None:
pl_event_content = {"users_default": "42"}
pl_event = make_event_from_dict(
H-Shay marked this conversation as resolved.
Show resolved Hide resolved
{
"room_id": TEST_ROOM_ID,
**_maybe_get_event_id_dict_for_room_version(RoomVersions.V10),
"type": "m.room.power_levels",
"sender": "@test:test.com",
"state_key": "",
"content": pl_event_content,
"signatures": {"test.com": {"ed25519:0": "some9signature"}},
},
room_version=RoomVersions.V10,
)

pl_event2_content = {"events": {"m.room.name": "42", "m.room.power_levels": 42}}
pl_event2 = make_event_from_dict(
{
"room_id": TEST_ROOM_ID,
**_maybe_get_event_id_dict_for_room_version(RoomVersions.V10),
"type": "m.room.power_levels",
"sender": "@test:test.com",
"state_key": "",
"content": pl_event2_content,
"signatures": {"test.com": {"ed25519:0": "some9signature"}},
},
room_version=RoomVersions.V10,
)

with self.assertRaises(AuthError):
event_auth._check_power_levels(
pl_event.room_version, pl_event, {("fake_type", "fake_key"): pl_event2}
)

with self.assertRaises(AuthError):
event_auth._check_power_levels(
pl_event.room_version, pl_event2, {("fake_type", "fake_key"): pl_event}
)


# helpers for making events
TEST_DOMAIN = "example.com"
Expand Down