Prepatory work for adding power level event to batched events (#14214)

This commit is contained in:
Shay 2022-10-18 09:58:47 -07:00 committed by GitHub
parent 2b940d2668
commit 847e2393f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 17 deletions

1
changelog.d/14214.misc Normal file
View File

@ -0,0 +1 @@
When authenticating batched events, check for auth events in batch as well as DB.

View File

@ -15,7 +15,18 @@
import logging import logging
import typing import typing
from typing import Any, Collection, Dict, Iterable, List, Optional, Set, Tuple, Union from typing import (
Any,
Collection,
Dict,
Iterable,
List,
Mapping,
Optional,
Set,
Tuple,
Union,
)
from canonicaljson import encode_canonical_json from canonicaljson import encode_canonical_json
from signedjson.key import decode_verify_key_bytes from signedjson.key import decode_verify_key_bytes
@ -134,6 +145,7 @@ def validate_event_for_room_version(event: "EventBase") -> None:
async def check_state_independent_auth_rules( async def check_state_independent_auth_rules(
store: _EventSourceStore, store: _EventSourceStore,
event: "EventBase", event: "EventBase",
batched_auth_events: Optional[Mapping[str, "EventBase"]] = None,
) -> None: ) -> None:
"""Check that an event complies with auth rules that are independent of room state """Check that an event complies with auth rules that are independent of room state
@ -143,6 +155,8 @@ async def check_state_independent_auth_rules(
Args: Args:
store: the datastore; used to fetch the auth events for validation store: the datastore; used to fetch the auth events for validation
event: the event being checked. event: the event being checked.
batched_auth_events: if the event being authed is part of a batch, any events
from the same batch that may be necessary to auth the current event
Raises: Raises:
AuthError if the checks fail AuthError if the checks fail
@ -162,6 +176,9 @@ async def check_state_independent_auth_rules(
redact_behaviour=EventRedactBehaviour.as_is, redact_behaviour=EventRedactBehaviour.as_is,
allow_rejected=True, allow_rejected=True,
) )
if batched_auth_events:
auth_events.update(batched_auth_events)
room_id = event.room_id room_id = event.room_id
auth_dict: MutableStateMap[str] = {} auth_dict: MutableStateMap[str] = {}
expected_auth_types = auth_types_for_event(event.room_version, event) expected_auth_types = auth_types_for_event(event.room_version, event)

View File

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import logging import logging
from typing import TYPE_CHECKING, Collection, List, Optional, Union from typing import TYPE_CHECKING, Collection, List, Mapping, Optional, Union
from synapse import event_auth from synapse import event_auth
from synapse.api.constants import ( from synapse.api.constants import (
@ -29,7 +29,6 @@ from synapse.event_auth import (
) )
from synapse.events import EventBase from synapse.events import EventBase
from synapse.events.builder import EventBuilder from synapse.events.builder import EventBuilder
from synapse.events.snapshot import EventContext
from synapse.types import StateMap, get_domain_from_id from synapse.types import StateMap, get_domain_from_id
if TYPE_CHECKING: if TYPE_CHECKING:
@ -51,12 +50,21 @@ class EventAuthHandler:
async def check_auth_rules_from_context( async def check_auth_rules_from_context(
self, self,
event: EventBase, event: EventBase,
context: EventContext, batched_auth_events: Optional[Mapping[str, EventBase]] = None,
) -> None: ) -> None:
"""Check an event passes the auth rules at its own auth events""" """Check an event passes the auth rules at its own auth events
await check_state_independent_auth_rules(self._store, event) Args:
event: event to be authed
batched_auth_events: if the event being authed is part of a batch, any events
from the same batch that may be necessary to auth the current event
"""
await check_state_independent_auth_rules(
self._store, event, batched_auth_events
)
auth_event_ids = event.auth_event_ids() auth_event_ids = event.auth_event_ids()
auth_events_by_id = await self._store.get_events(auth_event_ids) auth_events_by_id = await self._store.get_events(auth_event_ids)
if batched_auth_events:
auth_events_by_id.update(batched_auth_events)
check_state_dependent_auth_rules(event, auth_events_by_id.values()) check_state_dependent_auth_rules(event, auth_events_by_id.values())
def compute_auth_events( def compute_auth_events(

View File

@ -942,7 +942,7 @@ class FederationHandler:
# The remote hasn't signed it yet, obviously. We'll do the full checks # The remote hasn't signed it yet, obviously. We'll do the full checks
# when we get the event back in `on_send_join_request` # when we get the event back in `on_send_join_request`
await self._event_auth_handler.check_auth_rules_from_context(event, context) await self._event_auth_handler.check_auth_rules_from_context(event)
return event return event
async def on_invite_request( async def on_invite_request(
@ -1123,7 +1123,7 @@ class FederationHandler:
try: try:
# The remote hasn't signed it yet, obviously. We'll do the full checks # The remote hasn't signed it yet, obviously. We'll do the full checks
# when we get the event back in `on_send_leave_request` # when we get the event back in `on_send_leave_request`
await self._event_auth_handler.check_auth_rules_from_context(event, context) await self._event_auth_handler.check_auth_rules_from_context(event)
except AuthError as e: except AuthError as e:
logger.warning("Failed to create new leave %r because %s", event, e) logger.warning("Failed to create new leave %r because %s", event, e)
raise e raise e
@ -1182,7 +1182,7 @@ class FederationHandler:
try: try:
# The remote hasn't signed it yet, obviously. We'll do the full checks # The remote hasn't signed it yet, obviously. We'll do the full checks
# when we get the event back in `on_send_knock_request` # when we get the event back in `on_send_knock_request`
await self._event_auth_handler.check_auth_rules_from_context(event, context) await self._event_auth_handler.check_auth_rules_from_context(event)
except AuthError as e: except AuthError as e:
logger.warning("Failed to create new knock %r because %s", event, e) logger.warning("Failed to create new knock %r because %s", event, e)
raise e raise e
@ -1348,9 +1348,7 @@ class FederationHandler:
try: try:
validate_event_for_room_version(event) validate_event_for_room_version(event)
await self._event_auth_handler.check_auth_rules_from_context( await self._event_auth_handler.check_auth_rules_from_context(event)
event, context
)
except AuthError as e: except AuthError as e:
logger.warning("Denying new third party invite %r because %s", event, e) logger.warning("Denying new third party invite %r because %s", event, e)
raise e raise e
@ -1400,7 +1398,7 @@ class FederationHandler:
try: try:
validate_event_for_room_version(event) validate_event_for_room_version(event)
await self._event_auth_handler.check_auth_rules_from_context(event, context) await self._event_auth_handler.check_auth_rules_from_context(event)
except AuthError as e: except AuthError as e:
logger.warning("Denying third party invite %r because %s", event, e) logger.warning("Denying third party invite %r because %s", event, e)
raise e raise e

View File

@ -1360,8 +1360,16 @@ class EventCreationHandler:
else: else:
try: try:
validate_event_for_room_version(event) validate_event_for_room_version(event)
# If we are persisting a batch of events the event(s) needed to auth the
# current event may be part of the batch and will not be in the DB yet
event_id_to_event = {e.event_id: e for e, _ in events_and_context}
batched_auth_events = {}
for event_id in event.auth_event_ids():
auth_event = event_id_to_event.get(event_id)
if auth_event:
batched_auth_events[event_id] = auth_event
await self._event_auth_handler.check_auth_rules_from_context( await self._event_auth_handler.check_auth_rules_from_context(
event, context event, batched_auth_events
) )
except AuthError as err: except AuthError as err:
logger.warning("Denying new event %r because %s", event, err) logger.warning("Denying new event %r because %s", event, err)

View File

@ -229,9 +229,7 @@ class RoomCreationHandler:
}, },
) )
validate_event_for_room_version(tombstone_event) validate_event_for_room_version(tombstone_event)
await self._event_auth_handler.check_auth_rules_from_context( await self._event_auth_handler.check_auth_rules_from_context(tombstone_event)
tombstone_event, tombstone_context
)
# Upgrade the room # Upgrade the room
# #