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

Also fix wrong rule names for `is_user_mention` and `is_room_mention`.
This commit is contained in:
Mathieu Velten 2023-06-16 14:17:02 +02:00 committed by GitHub
parent f63d4a3a65
commit 0618bf94cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 17 deletions

1
changelog.d/15781.bugfix Normal file
View File

@ -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`.

View File

@ -142,7 +142,7 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
default_enabled: true, default_enabled: true,
}, },
PushRule { PushRule {
rule_id: Cow::Borrowed("global/override/.m.is_user_mention"), rule_id: Cow::Borrowed("global/override/.m.rule.is_user_mention"),
priority_class: 5, priority_class: 5,
conditions: Cow::Borrowed(&[Condition::Known( conditions: Cow::Borrowed(&[Condition::Known(
KnownCondition::ExactEventPropertyContainsType(EventPropertyIsTypeCondition { KnownCondition::ExactEventPropertyContainsType(EventPropertyIsTypeCondition {
@ -163,7 +163,7 @@ pub const BASE_APPEND_OVERRIDE_RULES: &[PushRule] = &[
default_enabled: true, default_enabled: true,
}, },
PushRule { 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, priority_class: 5,
conditions: Cow::Borrowed(&[ conditions: Cow::Borrowed(&[
Condition::Known(KnownCondition::EventPropertyIs(EventPropertyIsCondition { Condition::Known(KnownCondition::EventPropertyIs(EventPropertyIsCondition {

View File

@ -41,12 +41,7 @@ def format_push_rules_for_user(
rulearray.append(template_rule) rulearray.append(template_rule)
for type_key in ("pattern", "value"): _convert_type_to_value(template_rule, user)
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
template_rule["enabled"] = enabled template_rule["enabled"] = enabled
@ -63,19 +58,20 @@ def format_push_rules_for_user(
for c in template_rule["conditions"]: for c in template_rule["conditions"]:
c.pop("_cache_key", None) c.pop("_cache_key", None)
pattern_type = c.pop("pattern_type", None) _convert_type_to_value(c, user)
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()
return rules 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]: def _add_empty_priority_class_arrays(d: Dict[str, list]) -> Dict[str, list]:
for pc in PRIORITY_CLASS_MAP.keys(): for pc in PRIORITY_CLASS_MAP.keys():
d[pc] = [] d[pc] = []

View File

@ -412,3 +412,70 @@ class PushRuleAttributesTestCase(HomeserverTestCase):
) )
self.assertEqual(channel.code, 404) self.assertEqual(channel.code, 404)
self.assertEqual(channel.json_body["errcode"], Codes.NOT_FOUND) 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,
)