guard against accidental modification
parent
617e8a4653
commit
898196f1cc
|
@ -312,6 +312,12 @@ class EventBase(metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
return [e for e, _ in self.auth_events]
|
return [e for e, _ in self.auth_events]
|
||||||
|
|
||||||
|
def freeze(self):
|
||||||
|
"""'Freeze' the event dict, so it cannot be modified by accident"""
|
||||||
|
|
||||||
|
# this will be a no-op if the event dict is already frozen.
|
||||||
|
self._dict = freeze(self._dict)
|
||||||
|
|
||||||
|
|
||||||
class FrozenEvent(EventBase):
|
class FrozenEvent(EventBase):
|
||||||
format_version = EventFormatVersions.V1 # All events of this type are V1
|
format_version = EventFormatVersions.V1 # All events of this type are V1
|
||||||
|
|
|
@ -69,9 +69,10 @@ class ThirdPartyEventRules:
|
||||||
events = await self.store.get_events(prev_state_ids.values())
|
events = await self.store.get_events(prev_state_ids.values())
|
||||||
state_events = {(ev.type, ev.state_key): ev for ev in events.values()}
|
state_events = {(ev.type, ev.state_key): ev for ev in events.values()}
|
||||||
|
|
||||||
# The module can modify the event slightly if it wants, but caution should be
|
# Ensure that the event is frozen, to make sure that the module is not tempted
|
||||||
# exercised, and it's likely to go very wrong if applied to events received over
|
# to try to modify it. Any attempt to modify it at this point will invalidate
|
||||||
# federation.
|
# the hashes and signatures.
|
||||||
|
event.freeze()
|
||||||
|
|
||||||
return await self.third_party_rules.check_event_allowed(event, state_events)
|
return await self.third_party_rules.check_event_allowed(event, state_events)
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,26 @@ class ThirdPartyRulesTestCase(unittest.HomeserverTestCase):
|
||||||
self.render(request)
|
self.render(request)
|
||||||
self.assertEquals(channel.result["code"], b"403", channel.result)
|
self.assertEquals(channel.result["code"], b"403", channel.result)
|
||||||
|
|
||||||
|
def test_cannot_modify_event(self):
|
||||||
|
"""cannot accidentally modify an event before it is persisted"""
|
||||||
|
|
||||||
|
# first patch the event checker so that it will try to modify the event
|
||||||
|
async def check(ev: EventBase, state):
|
||||||
|
ev.content = {"x": "y"}
|
||||||
|
return True
|
||||||
|
|
||||||
|
current_rules_module().check_event_allowed = check
|
||||||
|
|
||||||
|
# now send the event
|
||||||
|
request, channel = self.make_request(
|
||||||
|
"PUT",
|
||||||
|
"/_matrix/client/r0/rooms/%s/send/modifyme/1" % self.room_id,
|
||||||
|
{"x": "x"},
|
||||||
|
access_token=self.tok,
|
||||||
|
)
|
||||||
|
self.render(request)
|
||||||
|
self.assertEqual(channel.result["code"], b"500", channel.result)
|
||||||
|
|
||||||
def test_modify_event(self):
|
def test_modify_event(self):
|
||||||
"""The module can return a modified version of the event"""
|
"""The module can return a modified version of the event"""
|
||||||
# first patch the event checker so that it will modify the event
|
# first patch the event checker so that it will modify the event
|
||||||
|
|
Loading…
Reference in New Issue