From 1666c0696a8891d39fd308e38e1b9b0042cabe34 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 1 Apr 2019 10:16:13 +0100 Subject: Track IS used to bind 3PIDs This will then be used to know which IS to default to when unbinding the threepid. --- synapse/storage/registration.py | 77 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'synapse/storage/registration.py') diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py index 9b6c28892c..7c8c683dee 100644 --- a/synapse/storage/registration.py +++ b/synapse/storage/registration.py @@ -328,6 +328,83 @@ class RegistrationWorkerStore(SQLBaseStore): desc="user_delete_threepids", ) + def add_user_bound_threepid(self, user_id, medium, address, id_server): + """The server proxied a bind request to the given identity server on + behalf of the given user. We need to remember this in case the user + asks us to unbind the threepid. + + Args: + user_id (str) + medium (str) + address (str) + id_server (str) + + Returns: + Deferred + """ + # We need to use an upsert, in case they user had already bound the + # threepid + return self._simple_upsert( + table="user_threepid_id_server", + keyvalues={ + "user_id": user_id, + "medium": medium, + "address": address, + "id_server": id_server, + }, + values={}, + insertion_values={}, + desc="add_user_bound_threepid", + ) + + def remove_user_bound_threepid(self, user_id, medium, address, id_server): + """The server proxied a bind request to the given identity server on + behalf of the given user. We need to remember this in case the user + asks us to unbind the threepid. + + Args: + user_id (str) + medium (str) + address (str) + id_server (str) + + Returns: + Deferred + """ + return self._simple_delete( + table="user_threepid_id_server", + keyvalues={ + "user_id": user_id, + "medium": medium, + "address": address, + "id_server": id_server, + }, + desc="remove_user_bound_threepid", + ) + + def get_id_servers_user_bound(self, user_id, medium, address): + """Get the list of identity servers that the server proxied bind + requests to for given user and threepid + + Args: + user_id (str) + medium (str) + address (str) + + Returns: + Deferred[list[str]]: Resolves to a list of identity servers + """ + return self._simple_select_onecol( + table="user_threepid_id_server", + keyvalues={ + "user_id": user_id, + "medium": medium, + "address": address, + }, + retcol="id_server", + desc="get_id_servers_user_bound", + ) + class RegistrationStore(RegistrationWorkerStore, background_updates.BackgroundUpdateStore): -- cgit 1.4.1 From 3715c124b3376adaeac53e0dae38f48f6d084f02 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Mon, 1 Apr 2019 13:23:18 +0100 Subject: Grandfather in existing user threepids We assume, as we did before, that users bound their threepid to one of the trusted identity servers. So we simply fill the new table with all threepids in `user_threepids` joined with the trusted identity servers. --- synapse/storage/registration.py | 35 ++++++++++++++++++++++ .../storage/schema/delta/53/user_threepid_id.sql | 2 ++ 2 files changed, 37 insertions(+) (limited to 'synapse/storage/registration.py') diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py index 7c8c683dee..4d64107e16 100644 --- a/synapse/storage/registration.py +++ b/synapse/storage/registration.py @@ -433,6 +433,10 @@ class RegistrationStore(RegistrationWorkerStore, # clear the background update. self.register_noop_background_update("refresh_tokens_device_index") + self.register_background_update_handler( + "user_threepids_grandfather", self._bg_user_threepids_grandfather, + ) + @defer.inlineCallbacks def add_access_token_to_user(self, user_id, token, device_id=None): """Adds an access token for the given user. @@ -815,3 +819,34 @@ class RegistrationStore(RegistrationWorkerStore, allow_none=True, desc="get_users_pending_deactivation", ) + + @defer.inlineCallbacks + def _bg_user_threepids_grandfather(self, progress, batch_size): + """We now track which identity servers a user binds their 3PID to, so + we need to handle the case of existing bindings where we didn't track + this. + + We do this by grandfathering in existing user threepids assuming that + they used one of the server configured trusted identity servers. + """ + + id_servers = set(self.config.trusted_third_party_id_servers) + + def _bg_user_threepids_grandfather_txn(txn): + sql = """ + INSERT INTO user_threepid_id_server + (user_id, medium, address, id_server) + SELECT user_id, medium, address, ? + FROM user_threepids + """ + + txn.executemany(sql, [(id_server,) for id_server in id_servers]) + + if id_servers: + yield self.runInteraction( + "_bg_user_threepids_grandfather", _bg_user_threepids_grandfather_txn, + ) + + yield self._end_background_update("user_threepids_grandfather") + + defer.returnValue(1) diff --git a/synapse/storage/schema/delta/53/user_threepid_id.sql b/synapse/storage/schema/delta/53/user_threepid_id.sql index a68b797f99..6c0b7ec0f7 100644 --- a/synapse/storage/schema/delta/53/user_threepid_id.sql +++ b/synapse/storage/schema/delta/53/user_threepid_id.sql @@ -25,3 +25,5 @@ CREATE UNIQUE INDEX user_threepid_id_server_idx ON user_threepid_id_server( user_id, medium, address, id_server ); +INSERT INTO background_updates (update_name, progress_json) VALUES + ('user_threepids_grandfather', '{}'); -- cgit 1.4.1 From c75e2017f16bf18127f4f70f69100b8343a139c4 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Tue, 2 Apr 2019 11:15:19 +0100 Subject: Fixup docstrings --- synapse/handlers/identity.py | 6 ++++-- synapse/storage/registration.py | 6 +++--- synapse/storage/schema/delta/53/user_threepid_id.sql | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) (limited to 'synapse/storage/registration.py') diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py index 4c127ba125..3eb112bf9d 100644 --- a/synapse/handlers/identity.py +++ b/synapse/handlers/identity.py @@ -150,14 +150,16 @@ class IdentityHandler(BaseHandler): Args: mxid (str): Matrix user ID of binding to be removed - threepid (dict): Dict with medium & address of binding to be removed + threepid (dict): Dict with medium & address of binding to be + removed, and an optional id_server. Raises: SynapseError: If we failed to contact the identity server Returns: Deferred[bool]: True on success, otherwise False if the identity - server doesn't support unbinding + server doesn't support unbinding (or no identity server found to + contact). """ if threepid.get("id_server"): id_servers = [threepid["id_server"]] diff --git a/synapse/storage/registration.py b/synapse/storage/registration.py index 4d64107e16..8ada655725 100644 --- a/synapse/storage/registration.py +++ b/synapse/storage/registration.py @@ -358,9 +358,9 @@ class RegistrationWorkerStore(SQLBaseStore): ) def remove_user_bound_threepid(self, user_id, medium, address, id_server): - """The server proxied a bind request to the given identity server on - behalf of the given user. We need to remember this in case the user - asks us to unbind the threepid. + """The server proxied an unbind request to the given identity server on + behalf of the given user, so we remove the mapping of threepid to + identity server. Args: user_id (str) diff --git a/synapse/storage/schema/delta/53/user_threepid_id.sql b/synapse/storage/schema/delta/53/user_threepid_id.sql index 6c0b7ec0f7..80c2c573b6 100644 --- a/synapse/storage/schema/delta/53/user_threepid_id.sql +++ b/synapse/storage/schema/delta/53/user_threepid_id.sql @@ -13,8 +13,8 @@ * limitations under the License. */ --- Tracks when -CREATE TABlE user_threepid_id_server ( +-- Tracks which identity server a user bound their threepid via. +CREATE TABLE user_threepid_id_server ( user_id TEXT NOT NULL, medium TEXT NOT NULL, address TEXT NOT NULL, -- cgit 1.4.1