summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/handlers/auth.py21
-rw-r--r--synapse/handlers/deactivate_account.py23
-rw-r--r--synapse/rest/admin/users.py9
-rw-r--r--synapse/rest/client/account.py14
-rw-r--r--tests/push/test_email.py2
5 files changed, 40 insertions, 29 deletions
diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index 8da017c3ba..ddbfbb2c18 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -1595,9 +1595,9 @@ class AuthHandler:
         # has successfully been created.
         await self._third_party_rules.on_threepid_bind(user_id, medium, address)
 
-    async def delete_and_unbind_threepid(
-        self, user_id: str, medium: str, address: str, id_server: Optional[str] = None
-    ) -> bool:
+    async def delete_local_threepid(
+        self, user_id: str, medium: str, address: str
+    ) -> None:
         """Attempts to unbind the 3pid on the identity servers and deletes it
         from the local database.
 
@@ -1605,25 +1605,11 @@ class AuthHandler:
             user_id: ID of user to remove the 3pid from.
             medium: The medium of the 3pid being removed: "email" or "msisdn".
             address: The 3pid address to remove.
-            id_server: Use the given identity server when unbinding
-                any threepids. If None then will attempt to unbind using the
-                identity server specified when binding (if known).
-
-        Returns:
-            Returns True if successfully unbound the 3pid on
-            the identity server, False if identity server doesn't support the
-            unbind API.
         """
-
         # 'Canonicalise' email addresses as per above
         if medium == "email":
             address = canonicalise_email(address)
 
-        identity_handler = self.hs.get_identity_handler()
-        result = await identity_handler.try_unbind_threepid(
-            user_id, {"medium": medium, "address": address, "id_server": id_server}
-        )
-
         # Inform Synapse modules that a 3PID association is about to be deleted.
         await self._third_party_rules.on_remove_user_third_party_identifier(
             user_id, medium, address
@@ -1643,7 +1629,6 @@ class AuthHandler:
             await self.store.delete_pusher_by_app_id_pushkey_user_id(
                 app_id="m.email", pushkey=address, user_id=user_id
             )
-        return result
 
     async def hash(self, password: str) -> str:
         """Computes a secure hash of password.
diff --git a/synapse/handlers/deactivate_account.py b/synapse/handlers/deactivate_account.py
index a10b89ec30..bb8eb1a8dc 100644
--- a/synapse/handlers/deactivate_account.py
+++ b/synapse/handlers/deactivate_account.py
@@ -100,13 +100,17 @@ class DeactivateAccountHandler:
         # unbinding
         identity_server_supports_unbinding = True
 
-        # Remove any threepids associated with this account locally and attempt to
-        # unbind them from identity server(s).
-        threepids = await self.store.user_get_threepids(user_id)
-        for threepid in threepids:
+        # Delete any known bindings of this user's 3PIDs on identity servers.
+        bound_threepids = await self.store.user_get_bound_threepids(user_id)
+        for threepid in bound_threepids:
             try:
-                result = await self._auth_handler.delete_and_unbind_threepid(
-                    user_id, threepid["medium"], threepid["address"], id_server
+                result = await self.hs.get_identity_handler().try_unbind_threepid(
+                    user_id,
+                    {
+                        "medium": threepid["medium"],
+                        "address": threepid["address"],
+                        "id_server": id_server,
+                    },
                 )
             except Exception:
                 # Do we want this to be a fatal error or should we carry on?
@@ -115,6 +119,13 @@ class DeactivateAccountHandler:
 
             identity_server_supports_unbinding &= result
 
+        # Delete all threepids associated with this account.
+        local_threepids = await self.store.user_get_threepids(user_id)
+        for threepid in local_threepids:
+            await self._auth_handler.delete_local_threepid(
+                user_id, threepid["medium"], threepid["address"]
+            )
+
         # delete any devices belonging to the user, which will also
         # delete corresponding access tokens.
         await self._device_handler.delete_all_devices_for_user(user_id)
diff --git a/synapse/rest/admin/users.py b/synapse/rest/admin/users.py
index 9276a81d9f..9e33012ae3 100644
--- a/synapse/rest/admin/users.py
+++ b/synapse/rest/admin/users.py
@@ -304,8 +304,13 @@ class UserRestServletV2(RestServlet):
                 # remove old threepids
                 for medium, address in del_threepids:
                     try:
-                        await self.auth_handler.delete_and_unbind_threepid(
-                            user_id, medium, address, None
+                        await self.hs.get_identity_handler().try_unbind_threepid(
+                            user_id,
+                            {"medium": medium, "address": address, "id_server": None},
+                        )
+
+                        await self.auth_handler.delete_local_threepid(
+                            user_id, medium, address
                         )
                     except Exception:
                         logger.exception("Failed to remove threepids")
diff --git a/synapse/rest/client/account.py b/synapse/rest/client/account.py
index 5b1e94c746..e7c6ea335c 100644
--- a/synapse/rest/client/account.py
+++ b/synapse/rest/client/account.py
@@ -770,8 +770,13 @@ class ThreepidDeleteRestServlet(RestServlet):
         user_id = requester.user.to_string()
 
         try:
-            ret = await self.auth_handler.delete_and_unbind_threepid(
-                user_id, body.medium, body.address, body.id_server
+            ret = await self.hs.get_identity_handler().try_unbind_threepid(
+                user_id,
+                {
+                    "medium": body.medium,
+                    "address": body.address,
+                    "id_server": body.id_server,
+                },
             )
         except Exception:
             # NB. This endpoint should succeed if there is nothing to
@@ -780,6 +785,11 @@ class ThreepidDeleteRestServlet(RestServlet):
             logger.exception("Failed to remove threepid")
             raise SynapseError(500, "Failed to remove threepid")
 
+        # Remove the local threepid association
+        await self.auth_handler.delete_local_threepid(
+            user_id, body.medium, body.address
+        )
+
         if ret:
             id_server_unbind_result = "success"
         else:
diff --git a/tests/push/test_email.py b/tests/push/test_email.py
index 5faf66e0ff..c7d317d978 100644
--- a/tests/push/test_email.py
+++ b/tests/push/test_email.py
@@ -367,7 +367,7 @@ class EmailPusherTests(HomeserverTestCase):
 
         # disassociate the user's email address
         self.get_success(
-            self.auth_handler.delete_and_unbind_threepid(
+            self.auth_handler.delete_local_threepid(
                 user_id=self.user_id, medium="email", address="a@example.com"
             )
         )