mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-25 02:55:46 +03:00
Pass room version object into event_auth.check and check_redaction (#6788)
These are easier to work with than the strings and we normally have one around. This fixes `FederationHander._persist_auth_tree` which was passing a RoomVersion object into event_auth.check instead of a string.
This commit is contained in:
parent
02b44db922
commit
a8ce7aeb43
8 changed files with 54 additions and 35 deletions
1
changelog.d/6788.misc
Normal file
1
changelog.d/6788.misc
Normal file
|
@ -0,0 +1 @@
|
|||
Record room versions in the `rooms` table.
|
|
@ -33,6 +33,7 @@ from synapse.api.errors import (
|
|||
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
|
||||
|
@ -77,15 +78,17 @@ class Auth(object):
|
|||
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
|
||||
|
|
|
@ -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.
|
||||
|
@ -23,17 +24,27 @@ from unpaddedbase64 import decode_base64
|
|||
|
||||
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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
|
|
@ -47,7 +47,7 @@ from synapse.api.errors import (
|
|||
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 (
|
||||
|
@ -1198,7 +1198,7 @@ class FederationHandler(BaseHandler):
|
|||
"""
|
||||
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,
|
||||
|
@ -1227,7 +1227,7 @@ class FederationHandler(BaseHandler):
|
|||
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
|
||||
)
|
||||
|
@ -1251,14 +1251,14 @@ class FederationHandler(BaseHandler):
|
|||
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
|
||||
|
@ -2022,6 +2022,7 @@ class FederationHandler(BaseHandler):
|
|||
|
||||
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:
|
||||
|
@ -2071,7 +2072,9 @@ class FederationHandler(BaseHandler):
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -2155,6 +2158,7 @@ class FederationHandler(BaseHandler):
|
|||
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(
|
||||
|
@ -2172,7 +2176,7 @@ class FederationHandler(BaseHandler):
|
|||
)
|
||||
|
||||
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
|
||||
|
|
|
@ -40,7 +40,7 @@ from synapse.api.errors import (
|
|||
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
|
||||
|
@ -962,9 +962,13 @@ class EventCreationHandler(object):
|
|||
)
|
||||
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)
|
||||
|
||||
if event_auth.check_redaction(room_version, event, auth_events=auth_events):
|
||||
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_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.
|
||||
|
|
|
@ -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,
|
||||
|
@ -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,
|
||||
|
|
|
@ -26,6 +26,7 @@ import synapse.state
|
|||
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
|
||||
|
||||
|
@ -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]
|
||||
|
@ -430,7 +432,7 @@ def _iterative_auth_checks(
|
|||
|
||||
try:
|
||||
event_auth.check(
|
||||
room_version,
|
||||
room_version_obj,
|
||||
event,
|
||||
auth_events,
|
||||
do_sig_check=False,
|
||||
|
|
|
@ -37,7 +37,7 @@ class EventAuthTestCase(unittest.TestCase):
|
|||
|
||||
# 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,
|
||||
|
@ -47,7 +47,7 @@ class EventAuthTestCase(unittest.TestCase):
|
|||
self.assertRaises(
|
||||
AuthError,
|
||||
event_auth.check,
|
||||
RoomVersions.V1.identifier,
|
||||
RoomVersions.V1,
|
||||
_random_state_event(joiner),
|
||||
auth_events,
|
||||
do_sig_check=False,
|
||||
|
@ -76,7 +76,7 @@ class EventAuthTestCase(unittest.TestCase):
|
|||
self.assertRaises(
|
||||
AuthError,
|
||||
event_auth.check,
|
||||
RoomVersions.V1.identifier,
|
||||
RoomVersions.V1,
|
||||
_random_state_event(pleb),
|
||||
auth_events,
|
||||
do_sig_check=False,
|
||||
|
@ -84,10 +84,7 @@ class EventAuthTestCase(unittest.TestCase):
|
|||
|
||||
# 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,
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue