summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/handlers/identity.py10
-rw-r--r--synapse/http/client.py30
-rw-r--r--synapse/server.py8
3 files changed, 42 insertions, 6 deletions
diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py
index 6a53c5eb47..41f978d990 100644
--- a/synapse/handlers/identity.py
+++ b/synapse/handlers/identity.py
@@ -35,7 +35,7 @@ class IdentityHandler(BaseHandler):
     def __init__(self, hs):
         super(IdentityHandler, self).__init__(hs)
 
-        self.http_client = hs.get_simple_http_client()
+        self.proxy_client = hs.get_matrix_proxy_client()
 
         self.trusted_id_servers = set(hs.config.trusted_third_party_id_servers)
         self.trust_any_id_server_just_for_testing_do_not_use = (
@@ -83,7 +83,7 @@ class IdentityHandler(BaseHandler):
 
         data = {}
         try:
-            data = yield self.http_client.get_json(
+            data = yield self.proxy_client.get_json(
                 "https://%s%s" % (
                     id_server,
                     "/_matrix/identity/api/v1/3pid/getValidated3pid"
@@ -118,7 +118,7 @@ class IdentityHandler(BaseHandler):
             raise SynapseError(400, "No client_secret in creds")
 
         try:
-            data = yield self.http_client.post_urlencoded_get_json(
+            data = yield self.proxy_client.post_urlencoded_get_json(
                 "https://%s%s" % (
                     id_server, "/_matrix/identity/api/v1/3pid/bind"
                 ),
@@ -151,7 +151,7 @@ class IdentityHandler(BaseHandler):
         params.update(kwargs)
 
         try:
-            data = yield self.http_client.post_json_get_json(
+            data = yield self.proxy_client.post_json_get_json(
                 "https://%s%s" % (
                     id_server,
                     "/_matrix/identity/api/v1/validate/email/requestToken"
@@ -185,7 +185,7 @@ class IdentityHandler(BaseHandler):
         params.update(kwargs)
 
         try:
-            data = yield self.http_client.post_json_get_json(
+            data = yield self.proxy_client.post_json_get_json(
                 "https://%s%s" % (
                     id_server,
                     "/_matrix/identity/api/v1/validate/msisdn/requestToken"
diff --git a/synapse/http/client.py b/synapse/http/client.py
index ca2f770f5d..c8b76b2191 100644
--- a/synapse/http/client.py
+++ b/synapse/http/client.py
@@ -145,6 +145,9 @@ class SimpleHttpClient(object):
 
         body = yield preserve_context_over_fn(readBody, response)
 
+        if response.code / 100 != 2:
+            raise CodeMessageException(response.code, body)
+
         defer.returnValue(json.loads(body))
 
     @defer.inlineCallbacks
@@ -306,6 +309,33 @@ class SimpleHttpClient(object):
         defer.returnValue((length, headers, response.request.absoluteURI, response.code))
 
 
+class MatrixProxyClient(object):
+    """
+    An HTTP client that proxies other Matrix endpoints, ie. if the remote endpoint
+    returns Matrix-style error response, this will raise the appropriate SynapseError
+    """
+    def __init__(self, hs):
+        self.simpleHttpClient = SimpleHttpClient(hs)
+
+    @defer.inlineCallbacks
+    def post_json_get_json(self, uri, post_json):
+        try:
+            result = yield self.simpleHttpClient.post_json_get_json(uri, post_json)
+            defer.returnValue(result)
+        except CodeMessageException as cme:
+            ex = None
+            try:
+                errbody = json.loads(cme.msg)
+                errcode = errbody['errcode']
+                errtext = errbody['error']
+                ex = SynapseError(cme.code, errtext, errcode)
+            except:
+                pass
+            if ex is not None:
+                raise ex
+            raise cme
+
+
 # XXX: FIXME: This is horribly copy-pasted from matrixfederationclient.
 # The two should be factored out.
 
diff --git a/synapse/server.py b/synapse/server.py
index 12754c89ae..8325d77a7a 100644
--- a/synapse/server.py
+++ b/synapse/server.py
@@ -49,7 +49,9 @@ from synapse.handlers.events import EventHandler, EventStreamHandler
 from synapse.handlers.initial_sync import InitialSyncHandler
 from synapse.handlers.receipts import ReceiptsHandler
 from synapse.handlers.read_marker import ReadMarkerHandler
-from synapse.http.client import SimpleHttpClient, InsecureInterceptableContextFactory
+from synapse.http.client import (
+    SimpleHttpClient, InsecureInterceptableContextFactory, MatrixProxyClient
+)
 from synapse.http.matrixfederationclient import MatrixFederationHttpClient
 from synapse.notifier import Notifier
 from synapse.push.pusherpool import PusherPool
@@ -128,6 +130,7 @@ class HomeServer(object):
         'filtering',
         'http_client_context_factory',
         'simple_http_client',
+        'matrix_proxy_client',
         'media_repository',
         'federation_transport_client',
         'federation_sender',
@@ -190,6 +193,9 @@ class HomeServer(object):
     def build_simple_http_client(self):
         return SimpleHttpClient(self)
 
+    def build_matrix_proxy_client(self):
+        return MatrixProxyClient(self)
+
     def build_v1auth(self):
         orf = Auth(self)
         # Matrix spec makes no reference to what HTTP status code is returned,