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

Commit 6c0b44a

Browse files
authored
Fix PushRuleEvaluator and Filter to work on frozendicts (#12100)
* Fix `PushRuleEvaluator` to work on frozendicts frozendicts do not (necessarily) inherit from dict, so this needs to handle them correctly. * Fix event filtering for frozen events Looks like this one was introduced by #11194.
1 parent 5565f45 commit 6c0b44a

File tree

5 files changed

+27
-6
lines changed

5 files changed

+27
-6
lines changed

Diff for: changelog.d/12100.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a long-standing bug which could cause push notifications to malfunction if `use_frozen_dicts` was set in the configuration.

Diff for: synapse/api/filtering.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
Dict,
2323
Iterable,
2424
List,
25+
Mapping,
2526
Optional,
2627
Set,
2728
TypeVar,
@@ -361,10 +362,10 @@ def _check(self, event: FilterEvent) -> bool:
361362
return self._check_fields(field_matchers)
362363
else:
363364
content = event.get("content")
364-
# Content is assumed to be a dict below, so ensure it is. This should
365+
# Content is assumed to be a mapping below, so ensure it is. This should
365366
# always be true for events, but account_data has been allowed to
366367
# have non-dict content.
367-
if not isinstance(content, dict):
368+
if not isinstance(content, Mapping):
368369
content = {}
369370

370371
sender = event.get("sender", None)

Diff for: synapse/push/push_rule_evaluator.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515

1616
import logging
1717
import re
18-
from typing import Any, Dict, List, Optional, Pattern, Tuple, Union
18+
from typing import Any, Dict, List, Mapping, Optional, Pattern, Tuple, Union
1919

2020
from matrix_common.regex import glob_to_regex, to_word_pattern
2121

2222
from synapse.events import EventBase
23-
from synapse.types import JsonDict, UserID
23+
from synapse.types import UserID
2424
from synapse.util.caches.lrucache import LruCache
2525

2626
logger = logging.getLogger(__name__)
@@ -223,7 +223,7 @@ def _glob_matches(glob: str, value: str, word_boundary: bool = False) -> bool:
223223

224224

225225
def _flatten_dict(
226-
d: Union[EventBase, JsonDict],
226+
d: Union[EventBase, Mapping[str, Any]],
227227
prefix: Optional[List[str]] = None,
228228
result: Optional[Dict[str, str]] = None,
229229
) -> Dict[str, str]:
@@ -234,7 +234,7 @@ def _flatten_dict(
234234
for key, value in d.items():
235235
if isinstance(value, str):
236236
result[".".join(prefix + [key])] = value.lower()
237-
elif isinstance(value, dict):
237+
elif isinstance(value, Mapping):
238238
_flatten_dict(value, prefix=(prefix + [key]), result=result)
239239

240240
return result

Diff for: tests/api/test_filtering.py

+10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from unittest.mock import patch
1919

2020
import jsonschema
21+
from frozendict import frozendict
2122

2223
from synapse.api.constants import EventContentFields
2324
from synapse.api.errors import SynapseError
@@ -327,6 +328,15 @@ def test_filter_labels(self):
327328

328329
self.assertFalse(Filter(self.hs, definition)._check(event))
329330

331+
# check it works with frozendicts too
332+
event = MockEvent(
333+
sender="@foo:bar",
334+
type="m.room.message",
335+
room_id="!secretbase:unknown",
336+
content=frozendict({EventContentFields.LABELS: ["#fun"]}),
337+
)
338+
self.assertTrue(Filter(self.hs, definition)._check(event))
339+
330340
def test_filter_not_labels(self):
331341
definition = {"org.matrix.not_labels": ["#fun"]}
332342
event = MockEvent(

Diff for: tests/push/test_push_rule_evaluator.py

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from typing import Any, Dict
1616

17+
import frozendict
18+
1719
from synapse.api.room_versions import RoomVersions
1820
from synapse.events import FrozenEvent
1921
from synapse.push import push_rule_evaluator
@@ -191,6 +193,13 @@ def test_event_match_non_body(self):
191193
"pattern should only match at the start/end of the value",
192194
)
193195

196+
# it should work on frozendicts too
197+
self._assert_matches(
198+
condition,
199+
frozendict.frozendict({"value": "FoobaZ"}),
200+
"patterns should match on frozendicts",
201+
)
202+
194203
# wildcards should match
195204
condition = {
196205
"kind": "event_match",

0 commit comments

Comments
 (0)