Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Implement rechecking of redactions for room versions v3 #4499

Merged
merged 15 commits into from Jan 29, 2019
Merged
2 changes: 0 additions & 2 deletions synapse/api/constants.py
Expand Up @@ -105,7 +105,6 @@ class RoomVersions(object):
V1 = "1"
V2 = "2"
V3 = "3" # Not currently fully supported, so we don't add to known versions below
VDH_TEST = "vdh-test-version"
STATE_V2_TEST = "state-v2-test"


Expand All @@ -117,7 +116,6 @@ class RoomVersions(object):
KNOWN_ROOM_VERSIONS = {
RoomVersions.V1,
RoomVersions.V2,
RoomVersions.VDH_TEST,
RoomVersions.STATE_V2_TEST,
}

Expand Down
2 changes: 1 addition & 1 deletion synapse/event_auth.py
Expand Up @@ -448,7 +448,7 @@ def check_redaction(room_version, event, auth_events):
if user_level >= redact_level:
return False

if room_version in (RoomVersions.V1, RoomVersions.V2, RoomVersions.VDH_TEST):
if room_version in (RoomVersions.V1, RoomVersions.V2,):
redacter_domain = get_domain_from_id(event.event_id)
redactee_domain = get_domain_from_id(event.redacts)
if redacter_domain == redactee_domain:
Expand Down
15 changes: 13 additions & 2 deletions synapse/events/__init__.py
Expand Up @@ -63,6 +63,18 @@ def get_send_on_behalf_of(self):
return getattr(self, "send_on_behalf_of", None)

def need_to_check_redaction(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can has docstring please - what does this mean?

"""Whether the redaction event needs to be rechecked when fetching
from the database.

Starting in room v3 redaction events are accepted up front, and later
checked to see if the redacter and redactee's domains match.

If the sender of the redaction event is allowed to redact due to auth
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"is allowed to redact any event"

rules, then this will always return false.

Returns:
bool
"""
return getattr(self, "recheck_redaction", False)


Expand Down Expand Up @@ -331,8 +343,7 @@ def room_version_to_event_format(room_version):
raise RuntimeError("Unrecognized room version %s" % (room_version,))

if room_version in (
RoomVersions.V1, RoomVersions.V2, RoomVersions.VDH_TEST,
RoomVersions.STATE_V2_TEST,
RoomVersions.V1, RoomVersions.V2, RoomVersions.STATE_V2_TEST,
):
return EventFormatVersions.V1
else:
Expand Down
2 changes: 1 addition & 1 deletion synapse/state/__init__.py
Expand Up @@ -608,7 +608,7 @@ def resolve_events_with_store(room_version, state_sets, event_map, state_res_sto
state_sets, event_map, state_res_store.get_events,
)
elif room_version in (
RoomVersions.VDH_TEST, RoomVersions.STATE_V2_TEST, RoomVersions.V2,
RoomVersions.STATE_V2_TEST, RoomVersions.V2,
):
return v2.resolve_events_with_store(
room_version, state_sets, event_map, state_res_store,
Expand Down
20 changes: 16 additions & 4 deletions synapse/storage/events_worker.py
Expand Up @@ -163,7 +163,6 @@ def _get_events(self, event_ids, check_redacted=True,

missing_events = yield self._enqueue_events(
missing_events_ids,
check_redacted=check_redacted,
allow_rejected=allow_rejected,
)

Expand All @@ -175,7 +174,7 @@ def _get_events(self, event_ids, check_redacted=True,
if not entry:
continue

# Some redactions in room version v3 need to be rechecked if we
# Starting in room version v3, some redactions need to be rechecked if we
# didn't have the redacted event at the time, so we recheck on read
# instead.
if not allow_rejected and entry.event.type == EventTypes.Redaction:
Expand All @@ -190,7 +189,7 @@ def _get_events(self, event_ids, check_redacted=True,
if orig and get_domain_from_id(orig.sender) == expected_domain:
# This redaction event is allowed. Mark as not needing a
# recheck.
entry.event.recheck_redaction = False
entry.event.internal_metadata.recheck_redaction = False
else:
# We don't have the event that is being redacted, so we
# assume that the event isn't authorized for now. (If we
Expand Down Expand Up @@ -334,7 +333,7 @@ def fire(evs, exc):
self.hs.get_reactor().callFromThread(fire, event_list, e)

@defer.inlineCallbacks
def _enqueue_events(self, events, check_redacted=True, allow_rejected=False):
def _enqueue_events(self, events, allow_rejected=False):
"""Fetches events from the database using the _event_fetch_list. This
allows batch and bulk fetching of events - it allows us to fetch events
without having to create a new transaction for each request for events.
Expand Down Expand Up @@ -467,6 +466,19 @@ def _get_event_from_row(self, internal_metadata, js, redacted,
# will serialise this field correctly
redacted_event.unsigned["redacted_because"] = because

# Starting in room version v3, some redactions need to be
# rechecked if we didn't have the redacted event at the
# time, so we recheck on read instead.
if because.internal_metadata.need_to_check_redaction():
expected_domain = get_domain_from_id(original_ev.sender)
if get_domain_from_id(because.sender) == expected_domain:
# This redaction event is allowed. Mark as not needing a
# recheck.
because.internal_metadata.recheck_redaction = False
else:
# Senders don't match, so the event isn't actually redacted
redacted_event = None

cache_entry = _EventCacheEntry(
event=original_ev,
redacted_event=redacted_event,
Expand Down