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

Add a test for a workaround concerning the behaviour of third-party rule modules and SynapseErrors. #11071

Merged
merged 7 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/11071.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a test for the workaround introduced in [\#11042](https://github.com/matrix-org/synapse/pull/11042) concerning the behaviour of third-party rule modules and `SynapseError`s.
56 changes: 50 additions & 6 deletions tests/rest/client/test_third_party_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import threading
from typing import Dict
from typing import TYPE_CHECKING, Dict, Optional, Tuple
from unittest.mock import Mock

from synapse.api.constants import EventTypes
from synapse.api.errors import SynapseError
from synapse.events import EventBase
from synapse.events.third_party_rules import load_legacy_third_party_event_rules
from synapse.module_api import ModuleApi
from synapse.rest import admin
from synapse.rest.client import login, room
from synapse.types import Requester, StateMap
from synapse.types import JsonDict, Requester, StateMap
from synapse.util.frozenutils import unfreeze

from tests import unittest

if TYPE_CHECKING:
from synapse.module_api import ModuleApi

thread_local = threading.local()


class LegacyThirdPartyRulesTestModule:
def __init__(self, config: Dict, module_api: ModuleApi):
def __init__(self, config: Dict, module_api: "ModuleApi"):
# keep a record of the "current" rules module, so that the test can patch
# it if desired.
thread_local.rules_module = self
Expand All @@ -50,7 +53,7 @@ def parse_config(config):


class LegacyDenyNewRooms(LegacyThirdPartyRulesTestModule):
def __init__(self, config: Dict, module_api: ModuleApi):
def __init__(self, config: Dict, module_api: "ModuleApi"):
super().__init__(config, module_api)

def on_create_room(
Expand All @@ -60,7 +63,7 @@ def on_create_room(


class LegacyChangeEvents(LegacyThirdPartyRulesTestModule):
def __init__(self, config: Dict, module_api: ModuleApi):
def __init__(self, config: Dict, module_api: "ModuleApi"):
super().__init__(config, module_api)

async def check_event_allowed(self, event: EventBase, state: StateMap[EventBase]):
Expand Down Expand Up @@ -136,6 +139,47 @@ async def check(ev, state):
)
self.assertEquals(channel.result["code"], b"403", channel.result)

def test_third_party_rules_workaround_synapse_errors_pass_through(self):
"""
Tests that the workaround introduced by https://github.com/matrix-org/synapse/pull/11042
is functional: that SynapseErrors are passed through from check_event_allowed
and bubble up to the web resource.

NEW MODULES SHOULD NOT MAKE USE OF THIS WORKAROUND!
This is a temporary workaround!
"""

class NastyHackException(SynapseError):
def error_dict(self):
"""
This overrides SynapseError's `error_dict` to nastily inject
JSON into the error response.
"""
result = super().error_dict()
result["nasty"] = "very"
return result

# add a callback that will raise our hacky exception
async def check(ev, state) -> Tuple[bool, Optional[JsonDict]]:
raise NastyHackException(429, "message")

self.hs.get_third_party_event_rules()._check_event_allowed_callbacks = [check]

# Make a request
channel = self.make_request(
"PUT",
"/_matrix/client/r0/rooms/%s/send/foo.bar.forbidden/2" % self.room_id,
{},
access_token=self.tok,
)
# Check the error code
self.assertEquals(channel.result["code"], b"429", channel.result)
# Check the JSON body has had the `nasty` key injected
self.assertEqual(
channel.json_body,
{"errcode": "M_UNKNOWN", "error": "message", "nasty": "very"},
)

def test_cannot_modify_event(self):
"""cannot accidentally modify an event before it is persisted"""

Expand Down