summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrendan Abolivier <babolivier@matrix.org>2019-06-17 18:53:13 +0100
committerBrendan Abolivier <babolivier@matrix.org>2019-06-17 20:24:07 +0100
commit112a48a5aa53c49794de988066f846ba4ae5fec1 (patch)
tree195d647a51d5f3f35ae82b9c83180c61c000dd55
parentImplement restricted rules and room creation hook (diff)
downloadsynapse-112a48a5aa53c49794de988066f846ba4ae5fec1.tar.xz
Implement 3PID invite hook
-rw-r--r--synapse/tchap/event_rules.py56
1 files changed, 49 insertions, 7 deletions
diff --git a/synapse/tchap/event_rules.py b/synapse/tchap/event_rules.py
index 471083fb1a..624336dab3 100644
--- a/synapse/tchap/event_rules.py
+++ b/synapse/tchap/event_rules.py
@@ -13,9 +13,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import email.utils
+
 from twisted.internet import defer
 
-from synapse.api.constants import EventTypes, Membership
+from synapse.api.constants import EventTypes
 from synapse.config._base import ConfigError
 from synapse.rulecheck.domain_rule_checker import DomainRuleChecker
 
@@ -26,7 +28,8 @@ ACCESS_RULE_DIRECT = "direct"
 
 
 class TchapEventRules(object):
-    def __init__(self, config):
+    def __init__(self, config, http_client):
+        self.http_client = http_client
         self.id_server = config["id_server"]
         self.domains_forbidden_when_restricted = config.get(
             "domains_forbidden_when_restricted", [],
@@ -66,13 +69,43 @@ class TchapEventRules(object):
             }
         })
 
+    @defer.inlineCallbacks
+    def check_threepid_can_be_invited(self, medium, address, state_events):
+        rule = self._get_rule_from_state(state_events)
+
+        if medium != "email":
+            defer.returnValue(False)
+
+        if rule != ACCESS_RULE_RESTRICTED:
+            # Only "restricted" requires filtering 3PID invites.
+            defer.returnValue(True)
+
+        parsed_address = email.utils.parseaddr(address)[1]
+        if parsed_address != address:
+            # Avoid reproducing the security issue described here:
+            # https://matrix.org/blog/2019/04/18/security-update-sydent-1-0-2
+            # It's probably not worth it but let's just be overly safe here.
+            defer.returnValue(False)
+
+        res = yield self.http_client.get_json(
+            "https://%s/_matrix/identity/api/v1/info" % (self.id_server,),
+            {
+                "medium": medium,
+                "address": address,
+            }
+        )
+
+        # Look for a domain that's not forbidden from being invited.
+        if not res.get("hs"):
+            defer.returnValue(False)
+        if res.get("hs") in self.domains_forbidden_when_restricted:
+            defer.returnValue(False)
+
+        defer.returnValue(True)
+
     def check_event_allowed(self, event, state_events):
         # TODO: add rules for sending the access rules event
-        access_rules = state_events.get((ACCESS_RULES_TYPE, ""))
-        if access_rules is None:
-            rule = ACCESS_RULE_RESTRICTED
-        else:
-            rule = access_rules.content.get("rule")
+        rule = self._get_rule_from_state(state_events)
 
         if rule == ACCESS_RULE_RESTRICTED:
             ret = self._apply_restricted(event)
@@ -157,6 +190,15 @@ class TchapEventRules(object):
         return True
 
     @staticmethod
+    def _get_rule_from_state(state_events):
+        access_rules = state_events.get((ACCESS_RULES_TYPE, ""))
+        if access_rules is None:
+            rule = ACCESS_RULE_RESTRICTED
+        else:
+            rule = access_rules.content.get("rule")
+        return rule
+
+    @staticmethod
     def _is_invite_from_threepid(invite, threepid_invite):
         token = invite.content.get("third_party_signed", {}).get("token", "")
         return token == threepid_invite.state_key