Skip to content
Snippets Groups Projects
Unverified Commit 2622b28c authored by Richard van der Hoff's avatar Richard van der Hoff Committed by GitHub
Browse files

Inline `_check_event_auth` for outliers (#10926)

* Inline `_check_event_auth` for outliers

When we are persisting an outlier, most of `_check_event_auth` is redundant:

 * `_update_auth_events_and_context_for_auth` does nothing, because the
   `input_auth_events` are (now) exactly the event's auth_events,
   which means that `missing_auth` is empty.

 * we don't care about soft-fail, kicking guest users or `send_on_behalf_of`
   for outliers

... so the only thing that matters is the auth itself, so let's just do that.

* `_auth_and_persist_fetched_events_inner`: de-async `prep`

`prep` no longer calls any `async` methods, so let's make it synchronous.

* Simplify `_check_event_auth`

We no longer need to support outliers here, which makes things rather simpler.

* changelog

* lint
parent eb2c7e51
No related branches found
No related tags found
No related merge requests found
Clean up some of the federation event authentication code for clarity. Clean up some of the federation event authentication code for clarity.
Clean up some of the federation event authentication code for clarity.
...@@ -68,11 +68,7 @@ from synapse.types import ( ...@@ -68,11 +68,7 @@ from synapse.types import (
UserID, UserID,
get_domain_from_id, get_domain_from_id,
) )
from synapse.util.async_helpers import ( from synapse.util.async_helpers import Linearizer, concurrently_execute
Linearizer,
concurrently_execute,
yieldable_gather_results,
)
from synapse.util.iterutils import batch_iter from synapse.util.iterutils import batch_iter
from synapse.util.retryutils import NotRetryingDestination from synapse.util.retryutils import NotRetryingDestination
from synapse.util.stringutils import shortstr from synapse.util.stringutils import shortstr
...@@ -1189,7 +1185,10 @@ class FederationEventHandler: ...@@ -1189,7 +1185,10 @@ class FederationEventHandler:
allow_rejected=True, allow_rejected=True,
) )
async def prep(event: EventBase) -> Optional[Tuple[EventBase, EventContext]]: room_version = await self._store.get_room_version_id(room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
def prep(event: EventBase) -> Optional[Tuple[EventBase, EventContext]]:
with nested_logging_context(suffix=event.event_id): with nested_logging_context(suffix=event.event_id):
auth = {} auth = {}
for auth_event_id in event.auth_event_ids(): for auth_event_id in event.auth_event_ids():
...@@ -1207,17 +1206,15 @@ class FederationEventHandler: ...@@ -1207,17 +1206,15 @@ class FederationEventHandler:
auth[(ae.type, ae.state_key)] = ae auth[(ae.type, ae.state_key)] = ae
context = EventContext.for_outlier() context = EventContext.for_outlier()
context = await self._check_event_auth( try:
origin, event_auth.check(room_version_obj, event, auth_events=auth)
event, except AuthError as e:
context, logger.warning("Rejecting %r because %s", event, e)
claimed_auth_event_map=auth, context.rejected = RejectedReason.AUTH_ERROR
)
return event, context return event, context
events_to_persist = ( events_to_persist = (x for x in (prep(event) for event in fetched_events) if x)
x for x in await yieldable_gather_results(prep, fetched_events) if x
)
await self.persist_events_and_notify(room_id, tuple(events_to_persist)) await self.persist_events_and_notify(room_id, tuple(events_to_persist))
async def _check_event_auth( async def _check_event_auth(
...@@ -1226,7 +1223,6 @@ class FederationEventHandler: ...@@ -1226,7 +1223,6 @@ class FederationEventHandler:
event: EventBase, event: EventBase,
context: EventContext, context: EventContext,
state: Optional[Iterable[EventBase]] = None, state: Optional[Iterable[EventBase]] = None,
claimed_auth_event_map: Optional[StateMap[EventBase]] = None,
backfilled: bool = False, backfilled: bool = False,
) -> EventContext: ) -> EventContext:
""" """
...@@ -1242,42 +1238,36 @@ class FederationEventHandler: ...@@ -1242,42 +1238,36 @@ class FederationEventHandler:
The state events used to check the event for soft-fail. If this is The state events used to check the event for soft-fail. If this is
not provided the current state events will be used. not provided the current state events will be used.
claimed_auth_event_map:
A map of (type, state_key) => event for the event's claimed auth_events.
Possibly including events that were rejected, or are in the wrong room.
Only populated when populating outliers.
backfilled: True if the event was backfilled. backfilled: True if the event was backfilled.
Returns: Returns:
The updated context object. The updated context object.
""" """
# claimed_auth_event_map should be given iff the event is an outlier # This method should only be used for non-outliers
assert bool(claimed_auth_event_map) == event.internal_metadata.outlier assert not event.internal_metadata.outlier
room_version = await self._store.get_room_version_id(event.room_id) room_version = await self._store.get_room_version_id(event.room_id)
room_version_obj = KNOWN_ROOM_VERSIONS[room_version] room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
if claimed_auth_event_map: # calculate what the auth events *should* be, to use as a basis for auth.
# if we have a copy of the auth events from the event, use that as the prev_state_ids = await context.get_prev_state_ids()
# basis for auth. auth_events_ids = self._event_auth_handler.compute_auth_events(
auth_events = claimed_auth_event_map event, prev_state_ids, for_verification=True
else: )
# otherwise, we calculate what the auth events *should* be, and use that auth_events_x = await self._store.get_events(auth_events_ids)
prev_state_ids = await context.get_prev_state_ids() calculated_auth_event_map = {
auth_events_ids = self._event_auth_handler.compute_auth_events( (e.type, e.state_key): e for e in auth_events_x.values()
event, prev_state_ids, for_verification=True }
)
auth_events_x = await self._store.get_events(auth_events_ids)
auth_events = {(e.type, e.state_key): e for e in auth_events_x.values()}
try: try:
( (
context, context,
auth_events_for_auth, auth_events_for_auth,
) = await self._update_auth_events_and_context_for_auth( ) = await self._update_auth_events_and_context_for_auth(
origin, event, context, auth_events origin,
event,
context,
calculated_auth_event_map=calculated_auth_event_map,
) )
except Exception: except Exception:
# We don't really mind if the above fails, so lets not fail # We don't really mind if the above fails, so lets not fail
...@@ -1289,7 +1279,7 @@ class FederationEventHandler: ...@@ -1289,7 +1279,7 @@ class FederationEventHandler:
"Ignoring failure and continuing processing of event.", "Ignoring failure and continuing processing of event.",
event.event_id, event.event_id,
) )
auth_events_for_auth = auth_events auth_events_for_auth = calculated_auth_event_map
try: try:
event_auth.check(room_version_obj, event, auth_events=auth_events_for_auth) event_auth.check(room_version_obj, event, auth_events=auth_events_for_auth)
...@@ -1425,7 +1415,7 @@ class FederationEventHandler: ...@@ -1425,7 +1415,7 @@ class FederationEventHandler:
origin: str, origin: str,
event: EventBase, event: EventBase,
context: EventContext, context: EventContext,
input_auth_events: StateMap[EventBase], calculated_auth_event_map: StateMap[EventBase],
) -> Tuple[EventContext, StateMap[EventBase]]: ) -> Tuple[EventContext, StateMap[EventBase]]:
"""Helper for _check_event_auth. See there for docs. """Helper for _check_event_auth. See there for docs.
...@@ -1443,19 +1433,17 @@ class FederationEventHandler: ...@@ -1443,19 +1433,17 @@ class FederationEventHandler:
event: event:
context: context:
input_auth_events: calculated_auth_event_map:
Map from (event_type, state_key) to event Our calculated auth_events based on the state of the room
at the event's position in the DAG.
Normally, our calculated auth_events based on the state of the room
at the event's position in the DAG, though occasionally (eg if the
event is an outlier), may be the auth events claimed by the remote
server.
Returns: Returns:
updated context, updated auth event map updated context, updated auth event map
""" """
# take a copy of input_auth_events before we modify it. assert not event.internal_metadata.outlier
auth_events: MutableStateMap[EventBase] = dict(input_auth_events)
# take a copy of calculated_auth_event_map before we modify it.
auth_events: MutableStateMap[EventBase] = dict(calculated_auth_event_map)
event_auth_events = set(event.auth_event_ids()) event_auth_events = set(event.auth_event_ids())
...@@ -1496,15 +1484,6 @@ class FederationEventHandler: ...@@ -1496,15 +1484,6 @@ class FederationEventHandler:
} }
) )
if event.internal_metadata.is_outlier():
# XXX: given that, for an outlier, we'll be working with the
# event's *claimed* auth events rather than those we calculated:
# (a) is there any point in this test, since different_auth below will
# obviously be empty
# (b) alternatively, why don't we do it earlier?
logger.info("Skipping auth_event fetch for outlier")
return context, auth_events
different_auth = event_auth_events.difference( different_auth = event_auth_events.difference(
e.event_id for e in auth_events.values() e.event_id for e in auth_events.values()
) )
......
...@@ -82,7 +82,6 @@ class MessageAcceptTests(unittest.HomeserverTestCase): ...@@ -82,7 +82,6 @@ class MessageAcceptTests(unittest.HomeserverTestCase):
event, event,
context, context,
state=None, state=None,
claimed_auth_event_map=None,
backfilled=False, backfilled=False,
): ):
return context return context
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment