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

push rules: fix internal conversion from _type to value #15781

Merged
merged 7 commits into from Jun 16, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15781.bugfix
@@ -0,0 +1 @@
Fix a bug in push rules handling leading to an invalid (per spec) `is_user_mention` rule sent to clients. Also fix wrong rule names for `is_user_mention` and `is_room_mention`.
4 changes: 2 additions & 2 deletions rust/src/push/base_rules.rs
Expand Up @@ -142,7 +142,7 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
default_enabled: true,
},
PushRule {
rule_id: Cow::Borrowed("global/override/.m.is_user_mention"),
rule_id: Cow::Borrowed("global/override/.m.rule.is_user_mention"),
MatMaul marked this conversation as resolved.
Show resolved Hide resolved
priority_class: 5,
conditions: Cow::Borrowed(&[Condition::Known(
KnownCondition::ExactEventPropertyContainsType(EventPropertyIsTypeCondition {
Expand All @@ -163,7 +163,7 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
default_enabled: true,
},
PushRule {
rule_id: Cow::Borrowed("global/override/.m.is_room_mention"),
rule_id: Cow::Borrowed("global/override/.m.rule.is_room_mention"),
priority_class: 5,
conditions: Cow::Borrowed(&[
Condition::Known(KnownCondition::EventPropertyIs(EventPropertyIsCondition {
Expand Down
26 changes: 11 additions & 15 deletions synapse/push/clientformat.py
Expand Up @@ -41,12 +41,7 @@ def format_push_rules_for_user(

rulearray.append(template_rule)

for type_key in ("pattern", "value"):
MatMaul marked this conversation as resolved.
Show resolved Hide resolved
type_value = template_rule.pop(f"{type_key}_type", None)
if type_value == "user_id":
template_rule[type_key] = user.to_string()
elif type_value == "user_localpart":
template_rule[type_key] = user.localpart
_convert_type_to_value(template_rule, user)

template_rule["enabled"] = enabled

Expand All @@ -63,19 +58,20 @@ def format_push_rules_for_user(
for c in template_rule["conditions"]:
c.pop("_cache_key", None)

pattern_type = c.pop("pattern_type", None)
if pattern_type == "user_id":
c["pattern"] = user.to_string()
elif pattern_type == "user_localpart":
c["pattern"] = user.localpart

sender_type = c.pop("sender_type", None)
if sender_type == "user_id":
c["sender"] = user.to_string()
_convert_type_to_value(c, user)

return rules


def _convert_type_to_value(rule_or_cond: Dict[str, Any], user: UserID) -> None:
for type_key in ("pattern", "value"):
type_value = rule_or_cond.pop(f"{type_key}_type", None)
if type_value == "user_id":
rule_or_cond[type_key] = user.to_string()
elif type_value == "user_localpart":
rule_or_cond[type_key] = user.localpart


def _add_empty_priority_class_arrays(d: Dict[str, list]) -> Dict[str, list]:
for pc in PRIORITY_CLASS_MAP.keys():
d[pc] = []
Expand Down
67 changes: 67 additions & 0 deletions tests/rest/client/test_push_rule_attrs.py
Expand Up @@ -412,3 +412,70 @@ def test_actions_404_when_put_non_existent_server_rule(self) -> None:
)
self.assertEqual(channel.code, 404)
self.assertEqual(channel.json_body["errcode"], Codes.NOT_FOUND)

def test_contains_user_name(self) -> None:
"""
Tests that `contains_user_name` rule is present and have proper value in `pattern`.
"""
username = "bob"
self.register_user(username, "pass")
token = self.login(username, "pass")

channel = self.make_request(
"GET",
"/pushrules/global/content/.m.rule.contains_user_name",
access_token=token,
)

self.assertEqual(channel.code, 200)

self.assertEqual(
{
"rule_id": ".m.rule.contains_user_name",
"default": True,
"enabled": True,
"pattern": username,
"actions": [
"notify",
{"set_tweak": "highlight"},
{"set_tweak": "sound", "value": "default"},
],
},
channel.json_body,
)

def test_is_user_mention(self) -> None:
"""
Tests that `is_user_mention` rule is present and have proper value in `value`.
"""
user = self.register_user("bob", "pass")
token = self.login("bob", "pass")

channel = self.make_request(
"GET",
"/pushrules/global/override/.m.rule.is_user_mention",
access_token=token,
)

self.assertEqual(channel.code, 200)

self.assertEqual(
{
"rule_id": ".m.rule.is_user_mention",
"default": True,
"enabled": True,
"conditions": [
{
"kind": "event_property_contains",
"key": "content.m\\.mentions.user_ids",
"value": user,
}
],
"actions": [
"notify",
{"set_tweak": "highlight"},
{"set_tweak": "sound", "value": "default"},
],
},
channel.json_body,
)