summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrew Morgan <andrew@amorgan.xyz>2019-09-09 15:39:52 +0100
committerAndrew Morgan <andrew@amorgan.xyz>2019-09-09 15:39:52 +0100
commit2f9d8dc5b968dd95339953a91e80c22738833bfa (patch)
tree84a8efc5a3a6cb6b6fbecb67ded29bde0869c835
parentAdd changelog (diff)
downloadsynapse-2f9d8dc5b968dd95339953a91e80c22738833bfa.tar.xz
Address review comments
-rw-r--r--synapse/rest/client/v2_alpha/account.py52
1 files changed, 44 insertions, 8 deletions
diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py
index 9869627b81..34646f6c26 100644
--- a/synapse/rest/client/v2_alpha/account.py
+++ b/synapse/rest/client/v2_alpha/account.py
@@ -21,7 +21,13 @@ from six.moves import http_client
 from twisted.internet import defer
 
 from synapse.api.constants import LoginType
-from synapse.api.errors import Codes, SynapseError, ThreepidValidationError
+from synapse.api.errors import (
+    Codes,
+    SynapseError,
+    ThreepidValidationError,
+    AuthError,
+    InvalidClientCredentialsError,
+)
 from synapse.config.emailconfig import ThreepidBehaviour
 from synapse.http.server import finish_request
 from synapse.http.servlet import (
@@ -419,7 +425,6 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def on_POST(self, request):
-        requester = yield self.auth.get_user_by_req(request)
         body = parse_json_object_from_request(request)
         assert_params_in_dict(
             body, ["id_server", "client_secret", "email", "send_attempt"]
@@ -437,12 +442,24 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
                 Codes.THREEPID_DENIED,
             )
 
+        requester = None
+        try:
+            requester = yield self.auth.get_user_by_req(request)
+        except (AuthError, InvalidClientCredentialsError) as e:
+            # No authentication provided, ignore
+            pass
+
         existing_user_id = yield self.store.get_user_id_by_threepid(
             "email", body["email"]
         )
 
-        # Allow this MSISDN to be rebound if the requester owns it
-        if existing_user_id != requester.user.to_string():
+        # If the request is authenticated, allow this MSISDN to be rebound if the requester
+        # owns it.
+        # Otherwise, deny the request if the 3PID exists
+        if (
+            (requester and existing_user_id != requester.user.to_string()) or
+            (requester is None and existing_user_id)
+        ):
             raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE)
 
         ret = yield self.identity_handler.requestEmailToken(
@@ -463,7 +480,6 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet):
 
     @defer.inlineCallbacks
     def on_POST(self, request):
-        requester = self.auth.get_user_by_req(request)
         body = parse_json_object_from_request(request)
         assert_params_in_dict(
             body,
@@ -485,10 +501,22 @@ class MsisdnThreepidRequestTokenRestServlet(RestServlet):
                 Codes.THREEPID_DENIED,
             )
 
+        requester = None
+        try:
+            requester = yield self.auth.get_user_by_req(request)
+        except (AuthError, InvalidClientCredentialsError) as e:
+            # No authentication provided, ignore
+            pass
+
         existing_user_id = yield self.store.get_user_id_by_threepid("msisdn", msisdn)
 
-        # Allow this MSISDN to be rebound if the requester owns it
-        if existing_user_id != requester.user.to_string():
+        # If the request is authenticated, allow this MSISDN to be rebound if the requester
+        # owns it.
+        # Otherwise, deny the request if the 3PID exists
+        if (
+            (requester and existing_user_id != requester.user.to_string()) or
+            (requester is None and existing_user_id)
+        ):
             raise SynapseError(400, "MSISDN is already in use", Codes.THREEPID_IN_USE)
 
         ret = yield self.identity_handler.requestMsisdnToken(
@@ -528,7 +556,6 @@ class ThreepidRestServlet(RestServlet):
 
         requester = yield self.auth.get_user_by_req(request)
         user_id = requester.user.to_string()
-
         threepid = yield self.identity_handler.threepid_from_creds(threepid_creds)
 
         if not threepid:
@@ -539,6 +566,15 @@ class ThreepidRestServlet(RestServlet):
                 logger.warn("Couldn't add 3pid: invalid response from ID server")
                 raise SynapseError(500, "Invalid response from ID Server")
 
+        existing_user_id = yield self.datastore.get_user_id_by_threepid(
+            threepid["medium"], threepid["address"]
+        )
+
+        # Check that the user is not trying to add an email that's already bound to another
+        # user
+        if existing_user_id != requester.user.to_string():
+            raise SynapseError(400, "This 3PID is already in use", Codes.THREEPID_IN_USE)
+
         yield self.auth_handler.add_threepid(
             user_id, threepid["medium"], threepid["address"], threepid["validated_at"]
         )