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

Split event_auth.check into two parts #10940

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
63 changes: 47 additions & 16 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,12 @@ def check(
Returns:
if the auth checks pass.
"""
assert isinstance(auth_events, dict)

if do_size_check:
_check_size_limits(event)

if not hasattr(event, "room_id"):
raise AuthError(500, "Event has no room_id: %s" % event)

room_id = event.room_id

# We need to ensure that the auth events are actually for the same room, to
# stop people from using powers they've been granted in other rooms for
# example.
for auth_event in auth_events.values():
if auth_event.room_id != room_id:
raise AuthError(
403,
"During auth for event %s in room %s, found event %s in the state "
"which is in room %s"
% (event.event_id, room_id, auth_event.event_id, auth_event.room_id),
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this (and the assertion above) are moved further down, into check_auth_rules_for_event. This could mean that we end up with a different AuthError for some bad events, but I don't think that matters: the important thing is that bad events are rejected and good events are accepted.

if do_sig_check:
sender_domain = get_domain_from_id(event.sender)

Expand Down Expand Up @@ -125,6 +109,53 @@ def check(
if not event.signatures.get(authoriser_domain):
raise AuthError(403, "Event not signed by authorising server")

check_auth_rules_for_event(room_version_obj, event, auth_events)


def check_auth_rules_for_event(
room_version_obj: RoomVersion, event: EventBase, auth_events: StateMap[EventBase]
) -> None:
"""Check that an event complies with the auth rules

Checks whether an event passes the auth rules with a given set of state events

Assumes that we have already checked that the event is the right shape (it has
enough signatures, has a room ID, etc). In other words:

- it's fine for use in state resolution, when we have already decided whether to
accept the event or not, and are now trying to decide whether it should make it
into the room state

- when we're doing the initial event auth, it is only suitable in combination with
a bunch of other tests.

Args:
room_version_obj: the version of the room
event: the event being checked.
auth_events: the room state to check the events against.

Raises:
AuthError if the checks fail
"""
assert isinstance(auth_events, dict)

# We need to ensure that the auth events are actually for the same room, to
# stop people from using powers they've been granted in other rooms for
# example.
#
# Arguably we don't need to do this when we're just doing state res, as presumably
# the state res algorithm isn't silly enough to give us events from different rooms.
# Still, it's easier to do it anyway.
room_id = event.room_id
for auth_event in auth_events.values():
if auth_event.room_id != room_id:
raise AuthError(
403,
"During auth for event %s in room %s, found event %s in the state "
"which is in room %s"
% (event.event_id, room_id, auth_event.event_id, auth_event.room_id),
)

# Implementation of https://matrix.org/docs/spec/rooms/v1#authorization-rules
#
# 1. If type is m.room.create:
Expand Down
8 changes: 2 additions & 6 deletions synapse/state/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,10 @@ def _resolve_auth_events(
auth_events[(prev_event.type, prev_event.state_key)] = prev_event
try:
# The signatures have already been checked at this point
event_auth.check(
event_auth.check_auth_rules_for_event(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means we skip the check that the event has a room_id attribute, but there's no way we could have got this far with an event without one. Similarly in a bunch of places below.

RoomVersions.V1,
event,
auth_events,
do_sig_check=False,
do_size_check=False,
)
prev_event = event
except AuthError:
Expand All @@ -349,12 +347,10 @@ def _resolve_normal_events(
for event in _ordered_events(events):
try:
# The signatures have already been checked at this point
event_auth.check(
event_auth.check_auth_rules_for_event(
RoomVersions.V1,
event,
auth_events,
do_sig_check=False,
do_size_check=False,
)
return event
except AuthError:
Expand Down
4 changes: 1 addition & 3 deletions synapse/state/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,12 +546,10 @@ async def _iterative_auth_checks(
auth_events[key] = event_map[ev_id]

try:
event_auth.check(
event_auth.check_auth_rules_for_event(
room_version,
event,
auth_events,
do_sig_check=False,
do_size_check=False,
)

resolved_state[(event.type, event.state_key)] = event_id
Expand Down
Loading