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

Pass room version object into event_auth.check and check_redaction #6788

Merged
merged 3 commits into from
Jan 28, 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/6788.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Record room versions in the `rooms` table.
7 changes: 5 additions & 2 deletions synapse/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
MissingClientTokenError,
ResourceLimitError,
)
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
from synapse.config.server import is_threepid_reserved
from synapse.types import StateMap, UserID
from synapse.util.caches import CACHE_SIZE_FACTOR, register_cache
Expand Down Expand Up @@ -77,15 +78,17 @@ def __init__(self, hs):
self._account_validity = hs.config.account_validity

@defer.inlineCallbacks
def check_from_context(self, room_version, event, context, do_sig_check=True):
def check_from_context(self, room_version: str, event, context, do_sig_check=True):
prev_state_ids = yield context.get_prev_state_ids()
auth_events_ids = yield self.compute_auth_events(
event, prev_state_ids, for_verification=True
)
auth_events = yield self.store.get_events(auth_events_ids)
auth_events = {(e.type, e.state_key): e for e in itervalues(auth_events)}

room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
event_auth.check(
room_version, event, auth_events=auth_events, do_sig_check=do_sig_check
room_version_obj, event, auth_events=auth_events, do_sig_check=do_sig_check
)

@defer.inlineCallbacks
Expand Down
34 changes: 21 additions & 13 deletions synapse/event_auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2014 - 2016 OpenMarket Ltd
# Copyright 2020 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -23,17 +24,27 @@

from synapse.api.constants import EventTypes, JoinRules, Membership
from synapse.api.errors import AuthError, EventSizeError, SynapseError
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, EventFormatVersions
from synapse.api.room_versions import (
KNOWN_ROOM_VERSIONS,
EventFormatVersions,
RoomVersion,
)
from synapse.types import UserID, get_domain_from_id

logger = logging.getLogger(__name__)


def check(room_version, event, auth_events, do_sig_check=True, do_size_check=True):
def check(
room_version_obj: RoomVersion,
event,
auth_events,
do_sig_check=True,
do_size_check=True,
):
""" Checks if this event is correctly authed.

Args:
room_version (str): the version of the room
room_version_obj: the version of the room
event: the event being checked.
auth_events (dict: event-key -> event): the existing room state.

Expand Down Expand Up @@ -97,10 +108,11 @@ def check(room_version, event, auth_events, do_sig_check=True, do_size_check=Tru
403, "Creation event's room_id domain does not match sender's"
)

room_version = event.content.get("room_version", "1")
if room_version not in KNOWN_ROOM_VERSIONS:
room_version_prop = event.content.get("room_version", "1")
if room_version_prop not in KNOWN_ROOM_VERSIONS:
raise AuthError(
403, "room appears to have unsupported version %s" % (room_version,)
403,
"room appears to have unsupported version %s" % (room_version_prop,),
)
# FIXME
logger.debug("Allowing! %s", event)
Expand Down Expand Up @@ -160,7 +172,7 @@ def check(room_version, event, auth_events, do_sig_check=True, do_size_check=Tru
_check_power_levels(event, auth_events)

if event.type == EventTypes.Redaction:
check_redaction(room_version, event, auth_events)
check_redaction(room_version_obj, event, auth_events)

logger.debug("Allowing! %s", event)

Expand Down Expand Up @@ -386,7 +398,7 @@ def _can_send_event(event, auth_events):
return True


def check_redaction(room_version, event, auth_events):
def check_redaction(room_version_obj: RoomVersion, event, auth_events):
"""Check whether the event sender is allowed to redact the target event.

Returns:
Expand All @@ -406,11 +418,7 @@ def check_redaction(room_version, event, auth_events):
if user_level >= redact_level:
return False

v = KNOWN_ROOM_VERSIONS.get(room_version)
if not v:
raise RuntimeError("Unrecognized room version %r" % (room_version,))

if v.event_format == EventFormatVersions.V1:
if room_version_obj.event_format == EventFormatVersions.V1:
redacter_domain = get_domain_from_id(event.event_id)
redactee_domain = get_domain_from_id(event.redacts)
if redacter_domain == redactee_domain:
Expand Down
18 changes: 11 additions & 7 deletions synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersion, RoomVersions
from synapse.crypto.event_signing import compute_event_signature
from synapse.event_auth import auth_types_for_event
from synapse.events import EventBase, room_version_to_event_format
from synapse.events import EventBase
from synapse.events.snapshot import EventContext
from synapse.events.validator import EventValidator
from synapse.logging.context import (
Expand Down Expand Up @@ -1198,7 +1198,7 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):
"""
logger.debug("Joining %s to %s", joinee, room_id)

origin, event, room_version = yield self._make_and_verify_event(
origin, event, room_version_obj = yield self._make_and_verify_event(
target_hosts,
room_id,
joinee,
Expand Down Expand Up @@ -1227,7 +1227,7 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):
except ValueError:
pass

event_format_version = room_version_to_event_format(room_version.identifier)
event_format_version = room_version_obj.event_format
ret = yield self.federation_client.send_join(
target_hosts, event, event_format_version
)
Expand All @@ -1251,14 +1251,14 @@ def do_invite_join(self, target_hosts, room_id, joinee, content):
room_id=room_id,
room_creator_user_id="",
is_public=False,
room_version=room_version,
room_version=room_version_obj,
)
except Exception:
# FIXME
pass

yield self._persist_auth_tree(
origin, auth_chain, state, event, room_version
origin, auth_chain, state, event, room_version_obj
)

# Check whether this room is the result of an upgrade of a room we already know
Expand Down Expand Up @@ -2022,6 +2022,7 @@ def _check_for_soft_fail(

if do_soft_fail_check:
room_version = yield self.store.get_room_version(event.room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]

# Calculate the "current state".
if state is not None:
Expand Down Expand Up @@ -2071,7 +2072,9 @@ def _check_for_soft_fail(
}

try:
event_auth.check(room_version, event, auth_events=current_auth_events)
event_auth.check(
room_version_obj, event, auth_events=current_auth_events
)
except AuthError as e:
logger.warning("Soft-failing %r because %s", event, e)
event.internal_metadata.soft_failed = True
Expand Down Expand Up @@ -2155,6 +2158,7 @@ def do_auth(self, origin, event, context, auth_events):
defer.Deferred[EventContext]: updated context object
"""
room_version = yield self.store.get_room_version(event.room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]

try:
context = yield self._update_auth_events_and_context_for_auth(
Expand All @@ -2172,7 +2176,7 @@ def do_auth(self, origin, event, context, auth_events):
)

try:
event_auth.check(room_version, event, auth_events=auth_events)
event_auth.check(room_version_obj, event, auth_events=auth_events)
except AuthError as e:
logger.warning("Failed auth resolution for %r because %s", event, e)
context.rejected = RejectedReason.AUTH_ERROR
Expand Down
8 changes: 6 additions & 2 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
NotFoundError,
SynapseError,
)
from synapse.api.room_versions import RoomVersions
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersions
from synapse.api.urls import ConsentURIBuilder
from synapse.events.validator import EventValidator
from synapse.logging.context import run_in_background
Expand Down Expand Up @@ -962,9 +962,13 @@ def is_inviter_member_event(e):
)
auth_events = yield self.store.get_events(auth_events_ids)
auth_events = {(e.type, e.state_key): e for e in auth_events.values()}

room_version = yield self.store.get_room_version(event.room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]

if event_auth.check_redaction(room_version, event, auth_events=auth_events):
if event_auth.check_redaction(
room_version_obj, event, auth_events=auth_events
):
# this user doesn't have 'redact' rights, so we need to do some more
# checks on the original event. Let's start by checking the original
# event exists.
Expand Down
4 changes: 2 additions & 2 deletions synapse/state/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def _resolve_auth_events(events, auth_events):
try:
# The signatures have already been checked at this point
event_auth.check(
RoomVersions.V1.identifier,
RoomVersions.V1,
event,
auth_events,
do_sig_check=False,
Expand All @@ -299,7 +299,7 @@ def _resolve_normal_events(events, auth_events):
try:
# The signatures have already been checked at this point
event_auth.check(
RoomVersions.V1.identifier,
RoomVersions.V1,
event,
auth_events,
do_sig_check=False,
Expand Down
4 changes: 3 additions & 1 deletion synapse/state/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from synapse import event_auth
from synapse.api.constants import EventTypes
from synapse.api.errors import AuthError
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
from synapse.events import EventBase
from synapse.types import StateMap

Expand Down Expand Up @@ -402,6 +403,7 @@ def _iterative_auth_checks(
Deferred[StateMap[str]]: Returns the final updated state
"""
resolved_state = base_state.copy()
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]

for event_id in event_ids:
event = event_map[event_id]
Expand Down Expand Up @@ -430,7 +432,7 @@ def _iterative_auth_checks(

try:
event_auth.check(
room_version,
room_version_obj,
event,
auth_events,
do_sig_check=False,
Expand Down
11 changes: 4 additions & 7 deletions tests/test_event_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_random_users_cannot_send_state_before_first_pl(self):

# creator should be able to send state
event_auth.check(
RoomVersions.V1.identifier,
RoomVersions.V1,
_random_state_event(creator),
auth_events,
do_sig_check=False,
Expand All @@ -47,7 +47,7 @@ def test_random_users_cannot_send_state_before_first_pl(self):
self.assertRaises(
AuthError,
event_auth.check,
RoomVersions.V1.identifier,
RoomVersions.V1,
_random_state_event(joiner),
auth_events,
do_sig_check=False,
Expand Down Expand Up @@ -76,18 +76,15 @@ def test_state_default_level(self):
self.assertRaises(
AuthError,
event_auth.check,
RoomVersions.V1.identifier,
RoomVersions.V1,
_random_state_event(pleb),
auth_events,
do_sig_check=False,
),

# king should be able to send state
event_auth.check(
RoomVersions.V1.identifier,
_random_state_event(king),
auth_events,
do_sig_check=False,
RoomVersions.V1, _random_state_event(king), auth_events, do_sig_check=False,
)


Expand Down