Read the room version from database when fetching events (#6874)

This is a precursor to giving EventBase objects the knowledge of which room version they belong to.
This commit is contained in:
Richard van der Hoff 2020-03-04 13:11:04 +00:00 committed by GitHub
parent 43f874055d
commit 8ef8fb2c1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 16 deletions

1
changelog.d/6874.misc Normal file
View file

@ -0,0 +1 @@
Refactoring work in preparation for changing the event redaction algorithm.

View file

@ -28,9 +28,12 @@ from twisted.internet import defer
from synapse.api.constants import EventTypes from synapse.api.constants import EventTypes
from synapse.api.errors import NotFoundError from synapse.api.errors import NotFoundError
from synapse.api.room_versions import EventFormatVersions from synapse.api.room_versions import (
from synapse.events import FrozenEvent, event_type_from_format_version # noqa: F401 KNOWN_ROOM_VERSIONS,
from synapse.events.snapshot import EventContext # noqa: F401 EventFormatVersions,
RoomVersions,
)
from synapse.events import make_event_from_dict
from synapse.events.utils import prune_event from synapse.events.utils import prune_event
from synapse.logging.context import LoggingContext, PreserveLoggingContext from synapse.logging.context import LoggingContext, PreserveLoggingContext
from synapse.metrics.background_process_metrics import run_as_background_process from synapse.metrics.background_process_metrics import run_as_background_process
@ -580,8 +583,49 @@ class EventsWorkerStore(SQLBaseStore):
# of a event format version, so it must be a V1 event. # of a event format version, so it must be a V1 event.
format_version = EventFormatVersions.V1 format_version = EventFormatVersions.V1
original_ev = event_type_from_format_version(format_version)( room_version_id = row["room_version_id"]
if not room_version_id:
# this should only happen for out-of-band membership events
if not internal_metadata.get("out_of_band_membership"):
logger.warning(
"Room %s for event %s is unknown", d["room_id"], event_id
)
continue
# take a wild stab at the room version based on the event format
if format_version == EventFormatVersions.V1:
room_version = RoomVersions.V1
elif format_version == EventFormatVersions.V2:
room_version = RoomVersions.V3
else:
room_version = RoomVersions.V5
else:
room_version = KNOWN_ROOM_VERSIONS.get(room_version_id)
if not room_version:
logger.error(
"Event %s in room %s has unknown room version %s",
event_id,
d["room_id"],
room_version_id,
)
continue
if room_version.event_format != format_version:
logger.error(
"Event %s in room %s with version %s has wrong format: "
"expected %s, was %s",
event_id,
d["room_id"],
room_version_id,
room_version.event_format,
format_version,
)
continue
original_ev = make_event_from_dict(
event_dict=d, event_dict=d,
room_version=room_version,
internal_metadata_dict=internal_metadata, internal_metadata_dict=internal_metadata,
rejected_reason=rejected_reason, rejected_reason=rejected_reason,
) )
@ -661,6 +705,12 @@ class EventsWorkerStore(SQLBaseStore):
of EventFormatVersions. 'None' means the event predates of EventFormatVersions. 'None' means the event predates
EventFormatVersions (so the event is format V1). EventFormatVersions (so the event is format V1).
* room_version_id (str|None): The version of the room which contains the event.
Hopefully one of RoomVersions.
Due to historical reasons, there may be a few events in the database which
do not have an associated room; in this case None will be returned here.
* rejected_reason (str|None): if the event was rejected, the reason * rejected_reason (str|None): if the event was rejected, the reason
why. why.
@ -676,17 +726,18 @@ class EventsWorkerStore(SQLBaseStore):
""" """
event_dict = {} event_dict = {}
for evs in batch_iter(event_ids, 200): for evs in batch_iter(event_ids, 200):
sql = ( sql = """\
"SELECT " SELECT
" e.event_id, " e.event_id,
" e.internal_metadata," e.internal_metadata,
" e.json," e.json,
" e.format_version, " e.format_version,
" rej.reason " r.room_version,
" FROM event_json as e" rej.reason
" LEFT JOIN rejections as rej USING (event_id)" FROM event_json as e
" WHERE " LEFT JOIN rooms r USING (room_id)
) LEFT JOIN rejections as rej USING (event_id)
WHERE """
clause, args = make_in_list_sql_clause( clause, args = make_in_list_sql_clause(
txn.database_engine, "e.event_id", evs txn.database_engine, "e.event_id", evs
@ -701,7 +752,8 @@ class EventsWorkerStore(SQLBaseStore):
"internal_metadata": row[1], "internal_metadata": row[1],
"json": row[2], "json": row[2],
"format_version": row[3], "format_version": row[3],
"rejected_reason": row[4], "room_version_id": row[4],
"rejected_reason": row[5],
"redactions": [], "redactions": [],
} }

View file

@ -15,6 +15,7 @@ import logging
from canonicaljson import encode_canonical_json from canonicaljson import encode_canonical_json
from synapse.api.room_versions import RoomVersions
from synapse.events import FrozenEvent, _EventInternalMetadata, make_event_from_dict from synapse.events import FrozenEvent, _EventInternalMetadata, make_event_from_dict
from synapse.events.snapshot import EventContext from synapse.events.snapshot import EventContext
from synapse.handlers.room import RoomEventSource from synapse.handlers.room import RoomEventSource
@ -58,6 +59,15 @@ class SlavedEventStoreTestCase(BaseSlavedStoreTestCase):
self.unpatches = [patch__eq__(_EventInternalMetadata), patch__eq__(FrozenEvent)] self.unpatches = [patch__eq__(_EventInternalMetadata), patch__eq__(FrozenEvent)]
return super(SlavedEventStoreTestCase, self).setUp() return super(SlavedEventStoreTestCase, self).setUp()
def prepare(self, *args, **kwargs):
super().prepare(*args, **kwargs)
self.get_success(
self.master_store.store_room(
ROOM_ID, USER_ID, is_public=False, room_version=RoomVersions.V1,
)
)
def tearDown(self): def tearDown(self):
[unpatch() for unpatch in self.unpatches] [unpatch() for unpatch in self.unpatches]