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

Enforce MSC2209: auth rules for notifications in power level event #7502

Merged
merged 4 commits into from
May 14, 2020
Merged
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/7502.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add additional authentication checks for m.room.power_levels event per [MSC2209](https://github.com/matrix-org/matrix-doc/pull/2209).
22 changes: 21 additions & 1 deletion synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ class RoomVersion(object):
enforce_key_validity = attr.ib() # bool

# bool: before MSC2261/MSC2432, m.room.aliases had special auth rules and redaction rules
special_case_aliases_auth = attr.ib(type=bool, default=False)
special_case_aliases_auth = attr.ib(type=bool)

# bool: MSC2209: Check 'notifications' key while verifying
# m.room.power_levels auth rules.
limit_notifications_power_levels = attr.ib(type=bool)


class RoomVersions(object):
Expand All @@ -69,6 +73,7 @@ class RoomVersions(object):
StateResolutionVersions.V1,
enforce_key_validity=False,
special_case_aliases_auth=True,
limit_notifications_power_levels=False,
)
V2 = RoomVersion(
"2",
Expand All @@ -77,6 +82,7 @@ class RoomVersions(object):
StateResolutionVersions.V2,
enforce_key_validity=False,
special_case_aliases_auth=True,
limit_notifications_power_levels=False,
)
V3 = RoomVersion(
"3",
Expand All @@ -85,6 +91,7 @@ class RoomVersions(object):
StateResolutionVersions.V2,
enforce_key_validity=False,
special_case_aliases_auth=True,
limit_notifications_power_levels=False,
)
V4 = RoomVersion(
"4",
Expand All @@ -93,6 +100,7 @@ class RoomVersions(object):
StateResolutionVersions.V2,
enforce_key_validity=False,
special_case_aliases_auth=True,
limit_notifications_power_levels=False,
)
V5 = RoomVersion(
"5",
Expand All @@ -101,6 +109,7 @@ class RoomVersions(object):
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=True,
limit_notifications_power_levels=False,
)
MSC2432_DEV = RoomVersion(
"org.matrix.msc2432",
Expand All @@ -109,6 +118,16 @@ class RoomVersions(object):
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=False,
limit_notifications_power_levels=False,
)
MSC2209_DEV = RoomVersion(
"org.matrix.msc2209",
RoomDisposition.UNSTABLE,
EventFormatVersions.V3,
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=True,
limit_notifications_power_levels=True,
)


Expand All @@ -121,5 +140,6 @@ class RoomVersions(object):
RoomVersions.V4,
RoomVersions.V5,
RoomVersions.MSC2432_DEV,
RoomVersions.MSC2209_DEV,
)
} # type: Dict[str, RoomVersion]
12 changes: 10 additions & 2 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def check(
_can_send_event(event, auth_events)

if event.type == EventTypes.PowerLevels:
_check_power_levels(event, auth_events)
_check_power_levels(room_version_obj, event, auth_events)

if event.type == EventTypes.Redaction:
check_redaction(room_version_obj, event, auth_events)
Expand Down Expand Up @@ -442,7 +442,7 @@ def check_redaction(room_version_obj: RoomVersion, event, auth_events):
raise AuthError(403, "You don't have permission to redact events")


def _check_power_levels(event, auth_events):
def _check_power_levels(room_version_obj, event, auth_events):
user_list = event.content.get("users", {})
# Validate users
for k, v in user_list.items():
Expand Down Expand Up @@ -484,6 +484,14 @@ def _check_power_levels(event, auth_events):
for ev_id in set(list(old_list) + list(new_list)):
levels_to_check.append((ev_id, "events"))

# MSC2209 specifies these checks should also be done for the "notifications"
# key.
if room_version_obj.limit_notifications_power_levels:
old_list = current_state.content.get("notifications", {})
new_list = event.content.get("notifications", {})
for ev_id in set(list(old_list) + list(new_list)):
levels_to_check.append((ev_id, "notifications"))

old_state = current_state.content
new_state = event.content

Expand Down
33 changes: 33 additions & 0 deletions tests/test_event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,39 @@ def test_msc2432_alias_event(self):
do_sig_check=False,
)

def test_msc2209(self):
"""
Notifications power levels get checked due to MSC2209.
"""
creator = "@creator:example.com"
pleb = "@joiner:example.com"

auth_events = {
("m.room.create", ""): _create_event(creator),
("m.room.member", creator): _join_event(creator),
("m.room.power_levels", ""): _power_levels_event(
creator, {"state_default": "30", "users": {pleb: "30"}}
),
("m.room.member", pleb): _join_event(pleb),
}

# pleb should be able to modify the notifications power level.
event_auth.check(
RoomVersions.V1,
_power_levels_event(pleb, {"notifications": {"room": 100}}),
auth_events,
do_sig_check=False,
)

# But an MSC2209 room rejects this change.
with self.assertRaises(AuthError):
event_auth.check(
RoomVersions.MSC2209_DEV,
_power_levels_event(pleb, {"notifications": {"room": 100}}),
auth_events,
do_sig_check=False,
)


# helpers for making events

Expand Down