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

Commit b194ac0

Browse files
committed
Ignore redactions of m.room.create events (#5701)
2 parents ae84a51 + 9c70a02 commit b194ac0

File tree

5 files changed

+57
-24
lines changed

5 files changed

+57
-24
lines changed

changelog.d/5701.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ignore redactions of m.room.create events.

synapse/api/auth.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -611,21 +611,6 @@ def compute_auth_events(self, event, current_state_ids, for_verification=False):
611611

612612
defer.returnValue(auth_ids)
613613

614-
def check_redaction(self, room_version, event, auth_events):
615-
"""Check whether the event sender is allowed to redact the target event.
616-
617-
Returns:
618-
True if the the sender is allowed to redact the target event if the
619-
target event was created by them.
620-
False if the sender is allowed to redact the target event with no
621-
further checks.
622-
623-
Raises:
624-
AuthError if the event sender is definitely not allowed to redact
625-
the target event.
626-
"""
627-
return event_auth.check_redaction(room_version, event, auth_events)
628-
629614
@defer.inlineCallbacks
630615
def check_can_change_room_list(self, room_id, user):
631616
"""Check if the user is allowed to edit the room's entry in the

synapse/handlers/message.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from twisted.internet import defer
2424
from twisted.internet.defer import succeed
2525

26+
from synapse import event_auth
2627
from synapse.api.constants import EventTypes, Membership, RelationTypes
2728
from synapse.api.errors import (
2829
AuthError,
@@ -784,25 +785,39 @@ def is_inviter_member_event(e):
784785
event.signatures.update(returned_invite.signatures)
785786

786787
if event.type == EventTypes.Redaction:
788+
original_event = yield self.store.get_event(
789+
event.redacts,
790+
check_redacted=False,
791+
get_prev_content=False,
792+
allow_rejected=False,
793+
allow_none=True,
794+
check_room_id=event.room_id,
795+
)
796+
797+
# we can make some additional checks now if we have the original event.
798+
if original_event:
799+
if original_event.type == EventTypes.Create:
800+
raise AuthError(403, "Redacting create events is not permitted")
801+
787802
prev_state_ids = yield context.get_prev_state_ids(self.store)
788803
auth_events_ids = yield self.auth.compute_auth_events(
789804
event, prev_state_ids, for_verification=True
790805
)
791806
auth_events = yield self.store.get_events(auth_events_ids)
792807
auth_events = {(e.type, e.state_key): e for e in auth_events.values()}
793808
room_version = yield self.store.get_room_version(event.room_id)
794-
if self.auth.check_redaction(room_version, event, auth_events=auth_events):
795-
original_event = yield self.store.get_event(
796-
event.redacts,
797-
check_redacted=False,
798-
get_prev_content=False,
799-
allow_rejected=False,
800-
allow_none=False,
801-
)
809+
810+
if event_auth.check_redaction(room_version, event, auth_events=auth_events):
811+
# this user doesn't have 'redact' rights, so we need to do some more
812+
# checks on the original event. Let's start by checking the original
813+
# event exists.
814+
if not original_event:
815+
raise NotFoundError("Could not find event %s" % (event.redacts,))
816+
802817
if event.user_id != original_event.user_id:
803818
raise AuthError(403, "You don't have permission to redact events")
804819

805-
# We've already checked.
820+
# all the checks are done.
806821
event.internal_metadata.recheck_redaction = False
807822

808823
if event.type == EventTypes.Create:

synapse/storage/events_worker.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ def get_events_as_list(
259259
continue
260260

261261
original_event = original_event_entry.event
262+
if original_event.type == EventTypes.Create:
263+
# we never serve redactions of Creates to clients.
264+
logger.info(
265+
"Withholding redaction %s of create event %s",
266+
event_id,
267+
redacted_event_id,
268+
)
269+
continue
262270

263271
if entry.event.internal_metadata.need_to_check_redaction():
264272
original_domain = get_domain_from_id(original_event.sender)
@@ -617,6 +625,10 @@ def _maybe_redact_event_row(self, original_ev, redactions):
617625
Deferred[EventBase|None]: if the event should be redacted, a pruned
618626
event object. Otherwise, None.
619627
"""
628+
if original_ev.type == "m.room.create":
629+
# we choose to ignore redactions of m.room.create events.
630+
return None
631+
620632
redaction_map = yield self._get_events_from_cache_or_db(redactions)
621633

622634
for redaction_id in redactions:

tests/rest/client/test_redactions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,23 @@ def test_redact_nonexistent_event(self):
157157
self.assertEqual(timeline[-2]["event_id"], msg_id)
158158
self.assertEqual(timeline[-2]["unsigned"]["redacted_by"], redaction_id)
159159
self.assertEqual(timeline[-2]["content"], {})
160+
161+
def test_redact_create_event(self):
162+
# control case: an existing event
163+
b = self.helper.send(room_id=self.room_id, tok=self.mod_access_token)
164+
msg_id = b["event_id"]
165+
self._redact_event(self.mod_access_token, self.room_id, msg_id)
166+
167+
# sync the room, to get the id of the create event
168+
timeline = self._sync_room_timeline(self.other_access_token, self.room_id)
169+
create_event_id = timeline[0]["event_id"]
170+
171+
# room moderators cannot send redactions for create events
172+
self._redact_event(
173+
self.mod_access_token, self.room_id, create_event_id, expect_code=403
174+
)
175+
176+
# and nor can normals
177+
self._redact_event(
178+
self.other_access_token, self.room_id, create_event_id, expect_code=403
179+
)

0 commit comments

Comments
 (0)