diff --git a/changelog.d/18103.bugfix b/changelog.d/18103.bugfix new file mode 100644 index 00000000000..11000d569fd --- /dev/null +++ b/changelog.d/18103.bugfix @@ -0,0 +1,3 @@ +Fixed a bug that disturbed room creation when a check_event_allowed callback was registered by a module and power_level Notifications mapping exists. + +Contributed by @c-cal diff --git a/synapse/events/__init__.py b/synapse/events/__init__.py index 8e9d27138ca..85d1f63bbc7 100644 --- a/synapse/events/__init__.py +++ b/synapse/events/__init__.py @@ -47,7 +47,7 @@ from synapse.synapse_rust.events import EventInternalMetadata from synapse.types import JsonDict, StrCollection from synapse.util.caches import intern_dict -from synapse.util.frozenutils import freeze +from synapse.util.frozenutils import freeze, unfreeze from synapse.util.stringutils import strtobool if TYPE_CHECKING: @@ -319,6 +319,12 @@ def freeze(self) -> None: # this will be a no-op if the event dict is already frozen. self._dict = freeze(self._dict) + def unfreeze(self) -> None: + """'Unfreeze' the event dict, so it can be modified afterwards""" + + # this will be a no-op if the event dict is already unfrozen. + self._dict = unfreeze(self._dict) + def __str__(self) -> str: return self.__repr__() diff --git a/synapse/module_api/callbacks/third_party_event_rules_callbacks.py b/synapse/module_api/callbacks/third_party_event_rules_callbacks.py index 9f7a04372de..6672f780ccc 100644 --- a/synapse/module_api/callbacks/third_party_event_rules_callbacks.py +++ b/synapse/module_api/callbacks/third_party_event_rules_callbacks.py @@ -293,6 +293,9 @@ async def check_event_allowed( # the hashes and signatures. event.freeze() + allow = True + event_dict = None + for callback in self._check_event_allowed_callbacks: try: res, replacement_data = await delay_cancellation( @@ -318,11 +321,15 @@ async def check_event_allowed( # Return if the event shouldn't be allowed or if the module came up with a # replacement dict for the event. if res is False: - return res, None + allow = False + break elif isinstance(replacement_data, dict): - return True, replacement_data + event_dict = replacement_data + break + + event.unfreeze() - return True, None + return allow, event_dict async def on_create_room( self, requester: Requester, config: dict, is_requester_admin: bool