diff --git a/synapse/event_auth.py b/synapse/event_auth.py index 66f50115e3..4b354dd6fb 100644 --- a/synapse/event_auth.py +++ b/synapse/event_auth.py @@ -66,6 +66,7 @@ from synapse.state import CREATE_KEY from synapse.storage.databases.main.events_worker import EventRedactBehaviour from synapse.types import ( MutableStateMap, + StateKey, StateMap, StrCollection, UserID, @@ -1200,8 +1201,8 @@ def get_public_keys(invite_event: "EventBase") -> list[dict[str, Any]]: def auth_types_for_event( room_version: RoomVersion, event: Union["EventBase", "EventBuilder"] -) -> set[tuple[str, str]]: - """Given an event, return a list of (EventType, StateKey) that may be +) -> set[StateKey]: + """Given an event, return a list of (state event type, state key) that may be needed to auth the event. The returned list may be a superset of what would actually be required depending on the full state of the room. diff --git a/synapse/storage/databases/main/sticky_events.py b/synapse/storage/databases/main/sticky_events.py index e3b8f54ebe..5113d95cdb 100644 --- a/synapse/storage/databases/main/sticky_events.py +++ b/synapse/storage/databases/main/sticky_events.py @@ -39,6 +39,7 @@ from synapse.storage.databases.main.state import StateGroupWorkerStore from synapse.storage.engines import PostgresEngine from synapse.storage.engines.sqlite import Sqlite3Engine from synapse.storage.util.id_generators import MultiWriterIdGenerator +from synapse.types import StateKey from synapse.types.state import StateFilter from synapse.util.duration import Duration from synapse.util.stringutils import shortstr @@ -480,21 +481,30 @@ class StickyEventsWorkerStore(StateGroupWorkerStore, CacheInvalidationWorkerStor room_id: The room the event IDs are in. soft_failed_event_ids: The soft-failed events to re-evaluate. """ - # Load all the soft-failed events to recheck, and pull out the precise state tuples we need + # Load all the soft-failed events to recheck soft_failed_event_map = await self.get_events( soft_failed_event_ids, allow_rejected=False ) - needed_tuples: set[tuple[str, str]] = set() - for ev in soft_failed_event_map.values(): - needed_tuples.update(event_auth.auth_types_for_event(ev.room_version, ev)) + # What (state event type, state key) tuples are needed as auth events for the + # soft-failed events we are reconsidering? + # e.g. [('m.room.member', '@user:example.org'), ('m.room.power_levels', ''), ...] + needed_state_tuples_for_auth: set[StateKey] = set() + for soft_failed_event in soft_failed_event_map.values(): + needed_state_tuples_for_auth.update( + event_auth.auth_types_for_event( + soft_failed_event.room_version, soft_failed_event + ) + ) # We know the events are otherwise authorised, so we only need to load the needed tuples from # the current state to check if the events pass auth. - current_state_map = await self.get_partial_filtered_current_state_ids( - room_id, StateFilter.from_types(needed_tuples) + current_auth_state_map = await self.get_partial_filtered_current_state_ids( + room_id, StateFilter.from_types(needed_state_tuples_for_auth) + ) + current_auth_state_event_ids: list[str] = list(current_auth_state_map.values()) + current_auth_events = await self.get_events_as_list( + current_auth_state_event_ids ) - current_state_ids_list = [e for _, e in current_state_map.items()] - current_auth_events = await self.get_events_as_list(current_state_ids_list) passing_event_ids: set[str] = set() for soft_failed_event in soft_failed_event_map.values(): if soft_failed_event.internal_metadata.policy_server_spammy: