Browse Source

Internal unbind endpoint not taking the same params as the public one

Mathieu Velten 2 years ago
parent
commit
278b9fc281

+ 14 - 6
sydent/http/servlets/authenticated_unbind_threepid_servlet.py

@@ -17,6 +17,7 @@
 from twisted.web.resource import Resource
 
 from sydent.http.servlets import get_args, jsonwrap, send_cors
+from sydent.http.servlets.threepidunbindservlet import check_req_params
 
 
 class AuthenticatedUnbindThreePidServlet(Resource):
@@ -31,13 +32,20 @@ class AuthenticatedUnbindThreePidServlet(Resource):
     @jsonwrap
     def render_POST(self, request):
         send_cors(request)
-        args = get_args(request, ('medium', 'address', 'mxid'))
-
-        threepid = {'medium': args['medium'], 'address': args['address']}
         
-        return self.sydent.threepidBinder.removeBinding(
-            threepid, args['mxid'],
-        )
+        if not check_req_params(request):
+            return
+
+        try:
+            self.sydent.threepidBinder.removeBinding(threepid, mxid)
+
+            request.write(dict_to_json_bytes({}))
+            request.finish()
+        except Exception as ex:
+            logger.exception("Exception whilst handling unbind")
+            request.setResponseCode(500)
+            request.write(dict_to_json_bytes({'errcode': 'M_UNKNOWN', 'error': str(ex)}))
+            request.finish()
 
     def render_OPTIONS(self, request):
         send_cors(request)

+ 28 - 21
sydent/http/servlets/threepidunbindservlet.py

@@ -39,6 +39,33 @@ from twisted.internet import defer
 logger = logging.getLogger(__name__)
 
 
+def check_req_params(request):
+    try:
+        # json.loads doesn't allow bytes in Python 3.5
+        body = json_decoder.decode(request.content.read().decode("UTF-8"))
+    except ValueError:
+        request.setResponseCode(400)
+        request.write(dict_to_json_bytes({'errcode': 'M_BAD_JSON', 'error': 'Malformed JSON'}))
+        request.finish()
+        return false
+
+    missing = [k for k in ("threepid", "mxid") if k not in body]
+    if len(missing) > 0:
+        request.setResponseCode(400)
+        msg = "Missing parameters: "+(",".join(missing))
+        request.write(dict_to_json_bytes({'errcode': 'M_MISSING_PARAMS', 'error': msg}))
+        request.finish()
+        return false
+
+    if 'medium' not in body['threepid'] or 'address' not in body['threepid']:
+        request.setResponseCode(400)
+        request.write(dict_to_json_bytes({'errcode': 'M_MISSING_PARAMS', 'error': 'Threepid lacks medium / address'}))
+        request.finish()
+        return false
+
+    return true
+
+
 class ThreePidUnbindServlet(Resource):
     def __init__(self, sydent):
         self.sydent = sydent
@@ -50,32 +77,12 @@ class ThreePidUnbindServlet(Resource):
     @defer.inlineCallbacks
     def _async_render_POST(self, request):
         try:
-            try:
-                # json.loads doesn't allow bytes in Python 3.5
-                body = json_decoder.decode(request.content.read().decode("UTF-8"))
-            except ValueError:
-                request.setResponseCode(400)
-                request.write(dict_to_json_bytes({'errcode': 'M_BAD_JSON', 'error': 'Malformed JSON'}))
-                request.finish()
-                return
-
-            missing = [k for k in ("threepid", "mxid") if k not in body]
-            if len(missing) > 0:
-                request.setResponseCode(400)
-                msg = "Missing parameters: "+(",".join(missing))
-                request.write(dict_to_json_bytes({'errcode': 'M_MISSING_PARAMS', 'error': msg}))
-                request.finish()
+            if not check_req_params(request):
                 return
 
             threepid = body['threepid']
             mxid = body['mxid']
 
-            if 'medium' not in threepid or 'address' not in threepid:
-                request.setResponseCode(400)
-                request.write(dict_to_json_bytes({'errcode': 'M_MISSING_PARAMS', 'error': 'Threepid lacks medium / address'}))
-                request.finish()
-                return
-
             # We now check for authentication in two different ways, depending
             # on the contents of the request. If the user has supplied "sid"
             # (the Session ID returned by Sydent during the original binding)