Stronger typing in the federation handler (#6480)
replace the event_info dict with an attrs thingpull/6488/head
parent
e1f4c83f41
commit
63d6ad1064
|
@ -0,0 +1 @@
|
|||
Refactor some code in the event authentication path for clarity.
|
|
@ -19,11 +19,13 @@
|
|||
|
||||
import itertools
|
||||
import logging
|
||||
from typing import Dict, Iterable, Optional, Sequence, Tuple
|
||||
|
||||
import six
|
||||
from six import iteritems, itervalues
|
||||
from six.moves import http_client, zip
|
||||
|
||||
import attr
|
||||
from signedjson.key import decode_verify_key_bytes
|
||||
from signedjson.sign import verify_signed_json
|
||||
from unpaddedbase64 import decode_base64
|
||||
|
@ -45,6 +47,7 @@ from synapse.api.errors import (
|
|||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, RoomVersions
|
||||
from synapse.crypto.event_signing import compute_event_signature
|
||||
from synapse.event_auth import auth_types_for_event
|
||||
from synapse.events import EventBase
|
||||
from synapse.events.snapshot import EventContext
|
||||
from synapse.events.validator import EventValidator
|
||||
from synapse.logging.context import (
|
||||
|
@ -72,6 +75,23 @@ from ._base import BaseHandler
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@attr.s
|
||||
class _NewEventInfo:
|
||||
"""Holds information about a received event, ready for passing to _handle_new_events
|
||||
|
||||
Attributes:
|
||||
event: the received event
|
||||
|
||||
state: the state at that event
|
||||
|
||||
auth_events: the auth_event map for that event
|
||||
"""
|
||||
|
||||
event = attr.ib(type=EventBase)
|
||||
state = attr.ib(type=Optional[Sequence[EventBase]], default=None)
|
||||
auth_events = attr.ib(type=Optional[Dict[Tuple[str, str], EventBase]], default=None)
|
||||
|
||||
|
||||
def shortstr(iterable, maxitems=5):
|
||||
"""If iterable has maxitems or fewer, return the stringification of a list
|
||||
containing those items.
|
||||
|
@ -597,14 +617,14 @@ class FederationHandler(BaseHandler):
|
|||
for e in auth_chain
|
||||
if e.event_id in auth_ids or e.type == EventTypes.Create
|
||||
}
|
||||
event_infos.append({"event": e, "auth_events": auth})
|
||||
event_infos.append(_NewEventInfo(event=e, auth_events=auth))
|
||||
seen_ids.add(e.event_id)
|
||||
|
||||
logger.info(
|
||||
"[%s %s] persisting newly-received auth/state events %s",
|
||||
room_id,
|
||||
event_id,
|
||||
[e["event"].event_id for e in event_infos],
|
||||
[e.event.event_id for e in event_infos],
|
||||
)
|
||||
yield self._handle_new_events(origin, event_infos)
|
||||
|
||||
|
@ -795,9 +815,9 @@ class FederationHandler(BaseHandler):
|
|||
|
||||
a.internal_metadata.outlier = True
|
||||
ev_infos.append(
|
||||
{
|
||||
"event": a,
|
||||
"auth_events": {
|
||||
_NewEventInfo(
|
||||
event=a,
|
||||
auth_events={
|
||||
(
|
||||
auth_events[a_id].type,
|
||||
auth_events[a_id].state_key,
|
||||
|
@ -805,7 +825,7 @@ class FederationHandler(BaseHandler):
|
|||
for a_id in a.auth_event_ids()
|
||||
if a_id in auth_events
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
# Step 1b: persist the events in the chunk we fetched state for (i.e.
|
||||
|
@ -817,10 +837,10 @@ class FederationHandler(BaseHandler):
|
|||
assert not ev.internal_metadata.is_outlier()
|
||||
|
||||
ev_infos.append(
|
||||
{
|
||||
"event": ev,
|
||||
"state": events_to_state[e_id],
|
||||
"auth_events": {
|
||||
_NewEventInfo(
|
||||
event=ev,
|
||||
state=events_to_state[e_id],
|
||||
auth_events={
|
||||
(
|
||||
auth_events[a_id].type,
|
||||
auth_events[a_id].state_key,
|
||||
|
@ -828,7 +848,7 @@ class FederationHandler(BaseHandler):
|
|||
for a_id in ev.auth_event_ids()
|
||||
if a_id in auth_events
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
yield self._handle_new_events(dest, ev_infos, backfilled=True)
|
||||
|
@ -1713,7 +1733,12 @@ class FederationHandler(BaseHandler):
|
|||
return context
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _handle_new_events(self, origin, event_infos, backfilled=False):
|
||||
def _handle_new_events(
|
||||
self,
|
||||
origin: str,
|
||||
event_infos: Iterable[_NewEventInfo],
|
||||
backfilled: bool = False,
|
||||
):
|
||||
"""Creates the appropriate contexts and persists events. The events
|
||||
should not depend on one another, e.g. this should be used to persist
|
||||
a bunch of outliers, but not a chunk of individual events that depend
|
||||
|
@ -1723,14 +1748,14 @@ class FederationHandler(BaseHandler):
|
|||
"""
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def prep(ev_info):
|
||||
event = ev_info["event"]
|
||||
def prep(ev_info: _NewEventInfo):
|
||||
event = ev_info.event
|
||||
with nested_logging_context(suffix=event.event_id):
|
||||
res = yield self._prep_event(
|
||||
origin,
|
||||
event,
|
||||
state=ev_info.get("state"),
|
||||
auth_events=ev_info.get("auth_events"),
|
||||
state=ev_info.state,
|
||||
auth_events=ev_info.auth_events,
|
||||
backfilled=backfilled,
|
||||
)
|
||||
return res
|
||||
|
@ -1744,7 +1769,7 @@ class FederationHandler(BaseHandler):
|
|||
|
||||
yield self.persist_events_and_notify(
|
||||
[
|
||||
(ev_info["event"], context)
|
||||
(ev_info.event, context)
|
||||
for ev_info, context in zip(event_infos, contexts)
|
||||
],
|
||||
backfilled=backfilled,
|
||||
|
@ -1846,7 +1871,14 @@ class FederationHandler(BaseHandler):
|
|||
yield self.persist_events_and_notify([(event, new_event_context)])
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _prep_event(self, origin, event, state, auth_events, backfilled):
|
||||
def _prep_event(
|
||||
self,
|
||||
origin: str,
|
||||
event: EventBase,
|
||||
state: Optional[Iterable[EventBase]],
|
||||
auth_events: Optional[Dict[Tuple[str, str], EventBase]],
|
||||
backfilled: bool,
|
||||
):
|
||||
"""
|
||||
|
||||
Args:
|
||||
|
@ -1854,7 +1886,7 @@ class FederationHandler(BaseHandler):
|
|||
event:
|
||||
state:
|
||||
auth_events:
|
||||
backfilled (bool)
|
||||
backfilled:
|
||||
|
||||
Returns:
|
||||
Deferred, which resolves to synapse.events.snapshot.EventContext
|
||||
|
@ -1890,15 +1922,16 @@ class FederationHandler(BaseHandler):
|
|||
return context
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _check_for_soft_fail(self, event, state, backfilled):
|
||||
def _check_for_soft_fail(
|
||||
self, event: EventBase, state: Optional[Iterable[EventBase]], backfilled: bool
|
||||
):
|
||||
"""Checks if we should soft fail the event, if so marks the event as
|
||||
such.
|
||||
|
||||
Args:
|
||||
event (FrozenEvent)
|
||||
state (dict|None): The state at the event if we don't have all the
|
||||
event's prev events
|
||||
backfilled (bool): Whether the event is from backfill
|
||||
event
|
||||
state: The state at the event if we don't have all the event's prev events
|
||||
backfilled: Whether the event is from backfill
|
||||
|
||||
Returns:
|
||||
Deferred
|
||||
|
|
Loading…
Reference in New Issue