Make 'event.redacts' never raise. (#6771)
* commit 'fa4d609e2': Make 'event.redacts' never raise. (#6771) Fixup changelog Fixup changelog Fixup changelog
This commit is contained in:
14
CHANGES.md
14
CHANGES.md
@@ -1,16 +1,20 @@
|
||||
Synapse 1.9.0 (2020-01-23)
|
||||
==========================
|
||||
|
||||
No significant changes.
|
||||
**WARNING**: As of this release, Synapse no longer supports versions of SQLite before 3.11, and will refuse to start when configured to use an older version. Administrators are recommended to migrate their database to Postgres (see instructions [here](docs/postgres.md)).
|
||||
|
||||
If your Synapse deployment uses workers, note that the reverse-proxy configurations for the `synapse.app.media_repository`, `synapse.app.federation_reader` and `synapse.app.event_creator` workers have changed, with the addition of a few paths (see the updated configurations [here](docs/workers.md#available-worker-applications)). Existing configurations will continue to work.
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Fix endpoint documentation for the List Rooms admin API. ([\#6770](https://github.com/matrix-org/synapse/issues/6770))
|
||||
|
||||
|
||||
Synapse 1.9.0rc1 (2020-01-22)
|
||||
=============================
|
||||
|
||||
**WARNING**: As of this release, Synapse no longer supports versions of SQLite before 3.11, and will refuse to start when configured to use an older version. Administrators are recommended to migrate their database to Postgres (see instructions [here](docs/postgres.md)).
|
||||
|
||||
If your Synapse deployment uses workers, note that the reverse-proxy configurations for the `synapse.app.media_repository`, `synapse.app.federation_reader` and `synapse.app.event_creator` have changed, with the addition of a few paths (see the updated configurations [here](docs/workers.md#available-worker-applications)).
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Fix endpoint documentation for the List Rooms admin api.
|
||||
1
changelog.d/6771.bugfix
Normal file
1
changelog.d/6771.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix persisting redaction events that have been redacted (or otherwise don't have a redacts key).
|
||||
@@ -116,16 +116,32 @@ class _EventInternalMetadata(object):
|
||||
return getattr(self, "redacted", False)
|
||||
|
||||
|
||||
def _event_dict_property(key):
|
||||
_SENTINEL = object()
|
||||
|
||||
|
||||
def _event_dict_property(key, default=_SENTINEL):
|
||||
"""Creates a new property for the given key that delegates access to
|
||||
`self._event_dict`.
|
||||
|
||||
The default is used if the key is missing from the `_event_dict`, if given,
|
||||
otherwise an AttributeError will be raised.
|
||||
|
||||
Note: If a default is given then `hasattr` will always return true.
|
||||
"""
|
||||
|
||||
# We want to be able to use hasattr with the event dict properties.
|
||||
# However, (on python3) hasattr expects AttributeError to be raised. Hence,
|
||||
# we need to transform the KeyError into an AttributeError
|
||||
def getter(self):
|
||||
|
||||
def getter_raises(self):
|
||||
try:
|
||||
return self._event_dict[key]
|
||||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
|
||||
def getter_default(self):
|
||||
return self._event_dict.get(key, default)
|
||||
|
||||
def setter(self, v):
|
||||
try:
|
||||
self._event_dict[key] = v
|
||||
@@ -138,7 +154,11 @@ def _event_dict_property(key):
|
||||
except KeyError:
|
||||
raise AttributeError(key)
|
||||
|
||||
return property(getter, setter, delete)
|
||||
if default is _SENTINEL:
|
||||
# No default given, so use the getter that raises
|
||||
return property(getter_raises, setter, delete)
|
||||
else:
|
||||
return property(getter_default, setter, delete)
|
||||
|
||||
|
||||
class EventBase(object):
|
||||
@@ -165,7 +185,7 @@ class EventBase(object):
|
||||
origin = _event_dict_property("origin")
|
||||
origin_server_ts = _event_dict_property("origin_server_ts")
|
||||
prev_events = _event_dict_property("prev_events")
|
||||
redacts = _event_dict_property("redacts")
|
||||
redacts = _event_dict_property("redacts", None)
|
||||
room_id = _event_dict_property("room_id")
|
||||
sender = _event_dict_property("sender")
|
||||
user_id = _event_dict_property("sender")
|
||||
|
||||
@@ -951,7 +951,7 @@ class EventsStore(
|
||||
elif event.type == EventTypes.Message:
|
||||
# Insert into the event_search table.
|
||||
self._store_room_message_txn(txn, event)
|
||||
elif event.type == EventTypes.Redaction:
|
||||
elif event.type == EventTypes.Redaction and event.redacts is not None:
|
||||
# Insert into the redactions table.
|
||||
self._store_redaction(txn, event)
|
||||
elif event.type == EventTypes.Retention:
|
||||
|
||||
@@ -287,7 +287,7 @@ class EventsWorkerStore(SQLBaseStore):
|
||||
# we have to recheck auth now.
|
||||
|
||||
if not allow_rejected and entry.event.type == EventTypes.Redaction:
|
||||
if not hasattr(entry.event, "redacts"):
|
||||
if entry.event.redacts is None:
|
||||
# A redacted redaction doesn't have a `redacts` key, in
|
||||
# which case lets just withhold the event.
|
||||
#
|
||||
|
||||
@@ -398,3 +398,38 @@ class RedactionTestCase(unittest.HomeserverTestCase):
|
||||
self.get_success(
|
||||
self.store.get_event(first_redact_event.event_id, allow_none=True)
|
||||
)
|
||||
|
||||
def test_store_redacted_redaction(self):
|
||||
"""Tests that we can store a redacted redaction.
|
||||
"""
|
||||
|
||||
self.get_success(
|
||||
self.inject_room_member(self.room1, self.u_alice, Membership.JOIN)
|
||||
)
|
||||
|
||||
builder = self.event_builder_factory.for_room_version(
|
||||
RoomVersions.V1,
|
||||
{
|
||||
"type": EventTypes.Redaction,
|
||||
"sender": self.u_alice.to_string(),
|
||||
"room_id": self.room1.to_string(),
|
||||
"content": {"reason": "foo"},
|
||||
},
|
||||
)
|
||||
|
||||
redaction_event, context = self.get_success(
|
||||
self.event_creation_handler.create_new_client_event(builder)
|
||||
)
|
||||
|
||||
self.get_success(
|
||||
self.storage.persistence.persist_event(redaction_event, context)
|
||||
)
|
||||
|
||||
# Now lets jump to the future where we have censored the redaction event
|
||||
# in the DB.
|
||||
self.reactor.advance(60 * 60 * 24 * 31)
|
||||
|
||||
# We just want to check that fetching the event doesn't raise an exception.
|
||||
self.get_success(
|
||||
self.store.get_event(redaction_event.event_id, allow_none=True)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user