Allowing specifying IS to use in unbind API.

By default the homeserver will use the identity server used during the
binding of the 3PID to unbind the 3PID. However, we need to allow
clients to explicitly ask the homeserver to unbind via a particular
identity server, for the case where the 3PID was bound out of band from
the homeserver.

Implements MSC915.
This commit is contained in:
Erik Johnston 2019-04-01 10:21:12 +01:00
parent 9fbbc3d9e5
commit 057715aaa2
4 changed files with 20 additions and 8 deletions

View File

@ -912,7 +912,7 @@ class AuthHandler(BaseHandler):
) )
@defer.inlineCallbacks @defer.inlineCallbacks
def delete_threepid(self, user_id, medium, address): def delete_threepid(self, user_id, medium, address, id_server=None):
"""Attempts to unbind the 3pid on the identity servers and deletes it """Attempts to unbind the 3pid on the identity servers and deletes it
from the local database. from the local database.
@ -920,6 +920,10 @@ class AuthHandler(BaseHandler):
user_id (str) user_id (str)
medium (str) medium (str)
address (str) address (str)
id_server (str|None): 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:
Deferred[bool]: Returns True if successfully unbound the 3pid on Deferred[bool]: Returns True if successfully unbound the 3pid on
@ -937,6 +941,7 @@ class AuthHandler(BaseHandler):
{ {
'medium': medium, 'medium': medium,
'address': address, 'address': address,
'id_server': id_server,
}, },
) )

View File

@ -43,12 +43,15 @@ class DeactivateAccountHandler(BaseHandler):
hs.get_reactor().callWhenRunning(self._start_user_parting) hs.get_reactor().callWhenRunning(self._start_user_parting)
@defer.inlineCallbacks @defer.inlineCallbacks
def deactivate_account(self, user_id, erase_data): def deactivate_account(self, user_id, erase_data, id_server=None):
"""Deactivate a user's account """Deactivate a user's account
Args: Args:
user_id (str): ID of user to be deactivated user_id (str): ID of user to be deactivated
erase_data (bool): whether to GDPR-erase the user's data erase_data (bool): whether to GDPR-erase the user's data
id_server (str|None): 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:
Deferred[bool]: True if identity server supports removing Deferred[bool]: True if identity server supports removing

View File

@ -159,11 +159,14 @@ class IdentityHandler(BaseHandler):
Deferred[bool]: True on success, otherwise False if the identity Deferred[bool]: True on success, otherwise False if the identity
server doesn't support unbinding server doesn't support unbinding
""" """
id_servers = yield self.store.get_id_servers_user_bound( if threepid.get("id_server"):
user_id=mxid, id_servers = [threepid["id_server"]]
medium=threepid["medium"], else:
address=threepid["address"], id_servers = yield self.store.get_id_servers_user_bound(
) user_id=mxid,
medium=threepid["medium"],
address=threepid["address"],
)
# We don't know where to unbind, so we don't have a choice but to return # We don't know where to unbind, so we don't have a choice but to return
if not id_servers: if not id_servers:

View File

@ -215,6 +215,7 @@ class DeactivateAccountRestServlet(RestServlet):
) )
result = yield self._deactivate_account_handler.deactivate_account( result = yield self._deactivate_account_handler.deactivate_account(
requester.user.to_string(), erase, requester.user.to_string(), erase,
id_server=body.get("id_server"),
) )
if result: if result:
id_server_unbind_result = "success" id_server_unbind_result = "success"
@ -380,7 +381,7 @@ class ThreepidDeleteRestServlet(RestServlet):
try: try:
ret = yield self.auth_handler.delete_threepid( ret = yield self.auth_handler.delete_threepid(
user_id, body['medium'], body['address'] user_id, body['medium'], body['address'], body.get("id_server"),
) )
except Exception: except Exception:
# NB. This endpoint should succeed if there is nothing to # NB. This endpoint should succeed if there is nothing to