summary refs log tree commit diff
path: root/synapse/push
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/push')
-rw-r--r--synapse/push/baserules.py364
-rw-r--r--synapse/push/bulk_push_rule_evaluator.py15
-rw-r--r--synapse/push/push_rule_evaluator.py20
3 files changed, 202 insertions, 197 deletions
diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py
index 8bac7fd6af..d8a0eda9fa 100644
--- a/synapse/push/baserules.py
+++ b/synapse/push/baserules.py
@@ -15,27 +15,25 @@
 from synapse.push.rulekinds import PRIORITY_CLASS_MAP, PRIORITY_CLASS_INVERSE_MAP
 
 
-def list_with_base_rules(rawrules, user_id):
+def list_with_base_rules(rawrules):
     ruleslist = []
 
     # shove the server default rules for each kind onto the end of each
     current_prio_class = PRIORITY_CLASS_INVERSE_MAP.keys()[-1]
 
     ruleslist.extend(make_base_prepend_rules(
-        user_id, PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
+        PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
     ))
 
     for r in rawrules:
         if r['priority_class'] < current_prio_class:
             while r['priority_class'] < current_prio_class:
                 ruleslist.extend(make_base_append_rules(
-                    user_id,
                     PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
                 ))
                 current_prio_class -= 1
                 if current_prio_class > 0:
                     ruleslist.extend(make_base_prepend_rules(
-                        user_id,
                         PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
                     ))
 
@@ -43,28 +41,26 @@ def list_with_base_rules(rawrules, user_id):
 
     while current_prio_class > 0:
         ruleslist.extend(make_base_append_rules(
-            user_id,
             PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
         ))
         current_prio_class -= 1
         if current_prio_class > 0:
             ruleslist.extend(make_base_prepend_rules(
-                user_id,
                 PRIORITY_CLASS_INVERSE_MAP[current_prio_class]
             ))
 
     return ruleslist
 
 
-def make_base_append_rules(user, kind):
+def make_base_append_rules(kind):
     rules = []
 
     if kind == 'override':
-        rules = make_base_append_override_rules()
+        rules = BASE_APPEND_OVRRIDE_RULES
     elif kind == 'underride':
-        rules = make_base_append_underride_rules(user)
+        rules = BASE_APPEND_UNDERRIDE_RULES
     elif kind == 'content':
-        rules = make_base_append_content_rules(user)
+        rules = BASE_APPEND_CONTENT_RULES
 
     for r in rules:
         r['priority_class'] = PRIORITY_CLASS_MAP[kind]
@@ -73,11 +69,11 @@ def make_base_append_rules(user, kind):
     return rules
 
 
-def make_base_prepend_rules(user, kind):
+def make_base_prepend_rules(kind):
     rules = []
 
     if kind == 'override':
-        rules = make_base_prepend_override_rules()
+        rules = BASE_PREPEND_OVERRIDE_RULES
 
     for r in rules:
         r['priority_class'] = PRIORITY_CLASS_MAP[kind]
@@ -86,180 +82,182 @@ def make_base_prepend_rules(user, kind):
     return rules
 
 
-def make_base_append_content_rules(user):
-    return [
-        {
-            'rule_id': 'global/content/.m.rule.contains_user_name',
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'content.body',
-                    'pattern': user.localpart,  # Matrix ID match
-                }
-            ],
-            'actions': [
-                'notify',
-                {
-                    'set_tweak': 'sound',
-                    'value': 'default',
-                }, {
-                    'set_tweak': 'highlight'
-                }
-            ]
-        },
-    ]
+BASE_APPEND_CONTENT_RULES = [
+    {
+        'rule_id': 'global/content/.m.rule.contains_user_name',
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'content.body',
+                'pattern_type': 'user_localpart'
+            }
+        ],
+        'actions': [
+            'notify',
+            {
+                'set_tweak': 'sound',
+                'value': 'default',
+            }, {
+                'set_tweak': 'highlight'
+            }
+        ]
+    },
+]
 
 
-def make_base_prepend_override_rules():
-    return [
-        {
-            'rule_id': 'global/override/.m.rule.master',
-            'enabled': False,
-            'conditions': [],
-            'actions': [
-                "dont_notify"
-            ]
-        }
-    ]
+BASE_PREPEND_OVERRIDE_RULES = [
+    {
+        'rule_id': 'global/override/.m.rule.master',
+        'enabled': False,
+        'conditions': [],
+        'actions': [
+            "dont_notify"
+        ]
+    }
+]
 
 
-def make_base_append_override_rules():
-    return [
-        {
-            'rule_id': 'global/override/.m.rule.suppress_notices',
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'content.msgtype',
-                    'pattern': 'm.notice',
-                }
-            ],
-            'actions': [
-                'dont_notify',
-            ]
-        }
-    ]
+BASE_APPEND_OVRRIDE_RULES = [
+    {
+        'rule_id': 'global/override/.m.rule.suppress_notices',
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'content.msgtype',
+                'pattern': 'm.notice',
+                '_id': '_suppress_notices',
+            }
+        ],
+        'actions': [
+            'dont_notify',
+        ]
+    }
+]
 
 
-def make_base_append_underride_rules(user):
-    return [
-        {
-            'rule_id': 'global/underride/.m.rule.call',
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'type',
-                    'pattern': 'm.call.invite',
-                }
-            ],
-            'actions': [
-                'notify',
-                {
-                    'set_tweak': 'sound',
-                    'value': 'ring'
-                }, {
-                    'set_tweak': 'highlight',
-                    'value': False
-                }
-            ]
-        },
-        {
-            'rule_id': 'global/underride/.m.rule.contains_display_name',
-            'conditions': [
-                {
-                    'kind': 'contains_display_name'
-                }
-            ],
-            'actions': [
-                'notify',
-                {
-                    'set_tweak': 'sound',
-                    'value': 'default'
-                }, {
-                    'set_tweak': 'highlight'
-                }
-            ]
-        },
-        {
-            'rule_id': 'global/underride/.m.rule.room_one_to_one',
-            'conditions': [
-                {
-                    'kind': 'room_member_count',
-                    'is': '2'
-                }
-            ],
-            'actions': [
-                'notify',
-                {
-                    'set_tweak': 'sound',
-                    'value': 'default'
-                }, {
-                    'set_tweak': 'highlight',
-                    'value': False
-                }
-            ]
-        },
-        {
-            'rule_id': 'global/underride/.m.rule.invite_for_me',
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'type',
-                    'pattern': 'm.room.member',
-                },
-                {
-                    'kind': 'event_match',
-                    'key': 'content.membership',
-                    'pattern': 'invite',
-                },
-                {
-                    'kind': 'event_match',
-                    'key': 'state_key',
-                    'pattern': user.to_string(),
-                },
-            ],
-            'actions': [
-                'notify',
-                {
-                    'set_tweak': 'sound',
-                    'value': 'default'
-                }, {
-                    'set_tweak': 'highlight',
-                    'value': False
-                }
-            ]
-        },
-        {
-            'rule_id': 'global/underride/.m.rule.member_event',
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'type',
-                    'pattern': 'm.room.member',
-                }
-            ],
-            'actions': [
-                'notify', {
-                    'set_tweak': 'highlight',
-                    'value': False
-                }
-            ]
-        },
-        {
-            'rule_id': 'global/underride/.m.rule.message',
-            'enabled': False,
-            'conditions': [
-                {
-                    'kind': 'event_match',
-                    'key': 'type',
-                    'pattern': 'm.room.message',
-                }
-            ],
-            'actions': [
-                'notify', {
-                    'set_tweak': 'highlight',
-                    'value': False
-                }
-            ]
-        }
-    ]
+BASE_APPEND_UNDERRIDE_RULES = [
+    {
+        'rule_id': 'global/underride/.m.rule.call',
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'type',
+                'pattern': 'm.call.invite',
+                '_id': '_call',
+            }
+        ],
+        'actions': [
+            'notify',
+            {
+                'set_tweak': 'sound',
+                'value': 'ring'
+            }, {
+                'set_tweak': 'highlight',
+                'value': False
+            }
+        ]
+    },
+    {
+        'rule_id': 'global/underride/.m.rule.contains_display_name',
+        'conditions': [
+            {
+                'kind': 'contains_display_name'
+            }
+        ],
+        'actions': [
+            'notify',
+            {
+                'set_tweak': 'sound',
+                'value': 'default'
+            }, {
+                'set_tweak': 'highlight'
+            }
+        ]
+    },
+    {
+        'rule_id': 'global/underride/.m.rule.room_one_to_one',
+        'conditions': [
+            {
+                'kind': 'room_member_count',
+                'is': '2'
+            }
+        ],
+        'actions': [
+            'notify',
+            {
+                'set_tweak': 'sound',
+                'value': 'default'
+            }, {
+                'set_tweak': 'highlight',
+                'value': False
+            }
+        ]
+    },
+    {
+        'rule_id': 'global/underride/.m.rule.invite_for_me',
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'type',
+                'pattern': 'm.room.member',
+                '_id': '_invite_type',
+            },
+            {
+                'kind': 'event_match',
+                'key': 'content.membership',
+                'pattern': 'invite',
+                '_id': '_invite_member',
+            },
+            {
+                'kind': 'event_match',
+                'key': 'state_key',
+                'pattern_type': 'user_id'
+            },
+        ],
+        'actions': [
+            'notify',
+            {
+                'set_tweak': 'sound',
+                'value': 'default'
+            }, {
+                'set_tweak': 'highlight',
+                'value': False
+            }
+        ]
+    },
+    {
+        'rule_id': 'global/underride/.m.rule.member_event',
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'type',
+                'pattern': 'm.room.member',
+                '_id': '_member',
+            }
+        ],
+        'actions': [
+            'notify', {
+                'set_tweak': 'highlight',
+                'value': False
+            }
+        ]
+    },
+    {
+        'rule_id': 'global/underride/.m.rule.message',
+        'enabled': False,
+        'conditions': [
+            {
+                'kind': 'event_match',
+                'key': 'type',
+                'pattern': 'm.room.message',
+                '_id': '_message',
+            }
+        ],
+        'actions': [
+            'notify', {
+                'set_tweak': 'highlight',
+                'value': False
+            }
+        ]
+    }
+]
diff --git a/synapse/push/bulk_push_rule_evaluator.py b/synapse/push/bulk_push_rule_evaluator.py
index b9f78fd598..f1910f7da7 100644
--- a/synapse/push/bulk_push_rule_evaluator.py
+++ b/synapse/push/bulk_push_rule_evaluator.py
@@ -22,7 +22,6 @@ import baserules
 from push_rule_evaluator import PushRuleEvaluatorForEvent
 
 from synapse.api.constants import EventTypes
-from synapse.types import UserID
 
 
 logger = logging.getLogger(__name__)
@@ -38,10 +37,10 @@ def decode_rule_json(rule):
 def _get_rules(room_id, user_ids, store):
     rules_by_user = yield store.bulk_get_push_rules(user_ids)
     rules_by_user = {
-        uid: baserules.list_with_base_rules(
-            [decode_rule_json(rule_list) for rule_list in rules_by_user.get(uid, [])],
-            UserID.from_string(uid),
-        )
+        uid: baserules.list_with_base_rules([
+            decode_rule_json(rule_list)
+            for rule_list in rules_by_user.get(uid, [])
+        ])
         for uid in user_ids
     }
     defer.returnValue(rules_by_user)
@@ -108,7 +107,7 @@ class BulkPushRuleEvaluator:
                     continue
 
                 matches = _condition_checker(
-                    evaluator, rule['conditions'], display_name, condition_cache
+                    evaluator, rule['conditions'], uid, display_name, condition_cache
                 )
                 if matches:
                     actions = [x for x in rule['actions'] if x != 'dont_notify']
@@ -118,7 +117,7 @@ class BulkPushRuleEvaluator:
         defer.returnValue(actions_by_user)
 
 
-def _condition_checker(evaluator, conditions, display_name, cache):
+def _condition_checker(evaluator, conditions, uid, display_name, cache):
     for cond in conditions:
         _id = cond.get("_id", None)
         if _id:
@@ -128,7 +127,7 @@ def _condition_checker(evaluator, conditions, display_name, cache):
             elif res is True:
                 continue
 
-        res = evaluator.matches(cond, display_name, None)
+        res = evaluator.matches(cond, uid, display_name, None)
         if _id:
             cache[_id] = res
 
diff --git a/synapse/push/push_rule_evaluator.py b/synapse/push/push_rule_evaluator.py
index 60d9f1f239..9332fe5c5e 100644
--- a/synapse/push/push_rule_evaluator.py
+++ b/synapse/push/push_rule_evaluator.py
@@ -91,8 +91,7 @@ class PushRuleEvaluator:
             rule['actions'] = json.loads(raw_rule['actions'])
             rules.append(rule)
 
-        user = UserID.from_string(self.user_id)
-        self.rules = baserules.list_with_base_rules(rules, user)
+        self.rules = baserules.list_with_base_rules(rules)
 
         self.enabled_map = enabled_map
 
@@ -150,7 +149,9 @@ class PushRuleEvaluator:
 
             matches = True
             for c in conditions:
-                matches = evaluator.matches(c, my_display_name, self.profile_tag)
+                matches = evaluator.matches(
+                    c, self.user_id, my_display_name, self.profile_tag
+                )
                 if not matches:
                     break
 
@@ -201,9 +202,9 @@ class PushRuleEvaluatorForEvent(object):
 
         return PushRuleEvaluatorForEvent(event, body_parts, room_member_count)
 
-    def matches(self, condition, display_name, profile_tag):
+    def matches(self, condition, user_id, display_name, profile_tag):
         if condition['kind'] == 'event_match':
-            return self._event_match(condition)
+            return self._event_match(condition, user_id)
         elif condition['kind'] == 'device':
             if 'profile_tag' not in condition:
                 return True
@@ -217,10 +218,17 @@ class PushRuleEvaluatorForEvent(object):
         else:
             return True
 
-    def _event_match(self, condition):
+    def _event_match(self, condition, user_id):
         pattern = condition.get('pattern', None)
 
         if not pattern:
+            pattern_type = condition.get('pattern_type', None)
+            if pattern_type == "user_id":
+                pattern = user_id
+            elif pattern_type == "user_localpart":
+                pattern = UserID.from_string(user_id).localpart
+
+        if not pattern:
             logger.warn("event_match condition with no pattern")
             return False