diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py
index abed5e7edb..b20d949689 100644
--- a/synapse/config/experimental.py
+++ b/synapse/config/experimental.py
@@ -81,3 +81,6 @@ class ExperimentalConfig(Config):
# MSC2815 (allow room moderators to view redacted event content)
self.msc2815_enabled: bool = experimental.get("msc2815_enabled", False)
+
+ # MSC3786 (Add a default push rule to ignore m.room.server_acl events)
+ self.msc3786_enabled: bool = experimental.get("msc3786_enabled", False)
diff --git a/synapse/push/baserules.py b/synapse/push/baserules.py
index f42f605f23..a17b35a605 100644
--- a/synapse/push/baserules.py
+++ b/synapse/push/baserules.py
@@ -277,6 +277,21 @@ BASE_APPEND_OVERRIDE_RULES: List[Dict[str, Any]] = [
],
"actions": ["dont_notify"],
},
+ # XXX: This is an experimental rule that is only enabled if msc3786_enabled
+ # is enabled, if it is not the rule gets filtered out in _load_rules() in
+ # PushRulesWorkerStore
+ {
+ "rule_id": "global/override/.org.matrix.msc3786.rule.room.server_acl",
+ "conditions": [
+ {
+ "kind": "event_match",
+ "key": "type",
+ "pattern": "m.room.server_acl",
+ "_cache_key": "_room_server_acl",
+ }
+ ],
+ "actions": ["dont_notify"],
+ },
]
diff --git a/synapse/storage/databases/main/push_rule.py b/synapse/storage/databases/main/push_rule.py
index eb85bbd392..4ed913e248 100644
--- a/synapse/storage/databases/main/push_rule.py
+++ b/synapse/storage/databases/main/push_rule.py
@@ -17,6 +17,7 @@ import logging
from typing import TYPE_CHECKING, Dict, List, Tuple, Union
from synapse.api.errors import StoreError
+from synapse.config.homeserver import ExperimentalConfig
from synapse.push.baserules import list_with_base_rules
from synapse.replication.slave.storage._slaved_id_tracker import SlavedIdTracker
from synapse.storage._base import SQLBaseStore, db_to_json
@@ -42,7 +43,21 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__)
-def _load_rules(rawrules, enabled_map):
+def _is_experimental_rule_enabled(
+ rule_id: str, experimental_config: ExperimentalConfig
+) -> bool:
+ """Used by `_load_rules` to filter out experimental rules when they
+ have not been enabled.
+ """
+ if (
+ rule_id == "global/override/.org.matrix.msc3786.rule.room.server_acl"
+ and not experimental_config.msc3786_enabled
+ ):
+ return False
+ return True
+
+
+def _load_rules(rawrules, enabled_map, experimental_config: ExperimentalConfig):
ruleslist = []
for rawrule in rawrules:
rule = dict(rawrule)
@@ -51,17 +66,26 @@ def _load_rules(rawrules, enabled_map):
rule["default"] = False
ruleslist.append(rule)
- # We're going to be mutating this a lot, so do a deep copy
- rules = list(list_with_base_rules(ruleslist))
+ # We're going to be mutating this a lot, so copy it. We also filter out
+ # any experimental default push rules that aren't enabled.
+ rules = [
+ rule
+ for rule in list_with_base_rules(ruleslist)
+ if _is_experimental_rule_enabled(rule["rule_id"], experimental_config)
+ ]
for i, rule in enumerate(rules):
rule_id = rule["rule_id"]
- if rule_id in enabled_map:
- if rule.get("enabled", True) != bool(enabled_map[rule_id]):
- # Rules are cached across users.
- rule = dict(rule)
- rule["enabled"] = bool(enabled_map[rule_id])
- rules[i] = rule
+
+ if rule_id not in enabled_map:
+ continue
+ if rule.get("enabled", True) == bool(enabled_map[rule_id]):
+ continue
+
+ # Rules are cached across users.
+ rule = dict(rule)
+ rule["enabled"] = bool(enabled_map[rule_id])
+ rules[i] = rule
return rules
@@ -141,7 +165,7 @@ class PushRulesWorkerStore(
enabled_map = await self.get_push_rules_enabled_for_user(user_id)
- return _load_rules(rows, enabled_map)
+ return _load_rules(rows, enabled_map, self.hs.config.experimental)
@cached(max_entries=5000)
async def get_push_rules_enabled_for_user(self, user_id) -> Dict[str, bool]:
@@ -200,7 +224,9 @@ class PushRulesWorkerStore(
enabled_map_by_user = await self.bulk_get_push_rules_enabled(user_ids)
for user_id, rules in results.items():
- results[user_id] = _load_rules(rules, enabled_map_by_user.get(user_id, {}))
+ results[user_id] = _load_rules(
+ rules, enabled_map_by_user.get(user_id, {}), self.hs.config.experimental
+ )
return results
|