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

Fix PushRuleEvaluator and Filter to work on frozendicts #12100

Merged
merged 2 commits into from
Feb 28, 2022
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/12100.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a long-standing bug which could cause push notifications to malfunction if `use_frozen_dicts` was set in the configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Fix a long-standing bug which could cause push notifications to malfunction if `use_frozen_dicts` was set in the configuration.
Fix a bug introduced in 1.47.0 which could cause push notifications to malfunction if `use_frozen_dicts` was set in the configuration.

5 changes: 3 additions & 2 deletions synapse/api/filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Dict,
Iterable,
List,
Mapping,
Optional,
Set,
TypeVar,
Expand Down Expand Up @@ -361,10 +362,10 @@ def _check(self, event: FilterEvent) -> bool:
return self._check_fields(field_matchers)
else:
content = event.get("content")
# Content is assumed to be a dict below, so ensure it is. This should
# Content is assumed to be a mapping below, so ensure it is. This should
# always be true for events, but account_data has been allowed to
# have non-dict content.
if not isinstance(content, dict):
if not isinstance(content, Mapping):
content = {}

sender = event.get("sender", None)
Expand Down
8 changes: 4 additions & 4 deletions synapse/push/push_rule_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@

import logging
import re
from typing import Any, Dict, List, Optional, Pattern, Tuple, Union
from typing import Any, Dict, List, Mapping, Optional, Pattern, Tuple, Union

from matrix_common.regex import glob_to_regex, to_word_pattern

from synapse.events import EventBase
from synapse.types import JsonDict, UserID
from synapse.types import UserID
from synapse.util.caches.lrucache import LruCache

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


def _flatten_dict(
d: Union[EventBase, JsonDict],
d: Union[EventBase, Mapping[str, Any]],
prefix: Optional[List[str]] = None,
result: Optional[Dict[str, str]] = None,
) -> Dict[str, str]:
Expand All @@ -234,7 +234,7 @@ def _flatten_dict(
for key, value in d.items():
if isinstance(value, str):
result[".".join(prefix + [key])] = value.lower()
elif isinstance(value, dict):
elif isinstance(value, Mapping):
_flatten_dict(value, prefix=(prefix + [key]), result=result)

return result
10 changes: 10 additions & 0 deletions tests/api/test_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from unittest.mock import patch

import jsonschema
from frozendict import frozendict

from synapse.api.constants import EventContentFields
from synapse.api.errors import SynapseError
Expand Down Expand Up @@ -327,6 +328,15 @@ def test_filter_labels(self):

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

# check it works with frozendicts too
event = MockEvent(
sender="@foo:bar",
type="m.room.message",
room_id="!secretbase:unknown",
content=frozendict({EventContentFields.LABELS: ["#fun"]}),
)
self.assertTrue(Filter(self.hs, definition)._check(event))

def test_filter_not_labels(self):
definition = {"org.matrix.not_labels": ["#fun"]}
event = MockEvent(
Expand Down
9 changes: 9 additions & 0 deletions tests/push/test_push_rule_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

from typing import Any, Dict

import frozendict

from synapse.api.room_versions import RoomVersions
from synapse.events import FrozenEvent
from synapse.push import push_rule_evaluator
Expand Down Expand Up @@ -191,6 +193,13 @@ def test_event_match_non_body(self):
"pattern should only match at the start/end of the value",
)

# it should work on frozendicts too
self._assert_matches(
condition,
frozendict.frozendict({"value": "FoobaZ"}),
"patterns should match on frozendicts",
)

# wildcards should match
condition = {
"kind": "event_match",
Expand Down