diff --git a/changelog.d/15781.bugfix b/changelog.d/15781.bugfix
new file mode 100644
index 0000000000..5faf59afee
--- /dev/null
+++ b/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`.
\ No newline at end of file
diff --git a/rust/src/push/base_rules.rs b/rust/src/push/base_rules.rs
index 9d6c304d92..7eea9313f0 100644
--- a/rust/src/push/base_rules.rs
+++ b/rust/src/push/base_rules.rs
@@ -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"),
priority_class: 5,
conditions: Cow::Borrowed(&[Condition::Known(
KnownCondition::ExactEventPropertyContainsType(EventPropertyIsTypeCondition {
@@ -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 {
diff --git a/synapse/push/clientformat.py b/synapse/push/clientformat.py
index 88b52c26a0..735cef0aed 100644
--- a/synapse/push/clientformat.py
+++ b/synapse/push/clientformat.py
@@ -41,12 +41,7 @@ def format_push_rules_for_user(
rulearray.append(template_rule)
- for type_key in ("pattern", "value"):
- 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
@@ -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] = []
diff --git a/tests/rest/client/test_push_rule_attrs.py b/tests/rest/client/test_push_rule_attrs.py
index 4f875b9289..5aca74475f 100644
--- a/tests/rest/client/test_push_rule_attrs.py
+++ b/tests/rest/client/test_push_rule_attrs.py
@@ -412,3 +412,70 @@ class PushRuleAttributesTestCase(HomeserverTestCase):
)
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,
+ )
|