mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-08-06 00:44:14 -04:00
Make cleaning up pushers depend on the device_id instead of the token_id (#15280)
This makes it so that we rely on the `device_id` to delete pushers on logout, instead of relying on the `access_token_id`. This ensures we're not removing pushers on token refresh, and prepares for a world without access token IDs (also known as the OIDC). This actually runs the `set_device_id_for_pushers` background update, which was forgotten in #13831. Note that for backwards compatibility it still deletes pushers based on the `access_token` until the background update finishes.
This commit is contained in:
parent
68a6717312
commit
5b70f240cf
15 changed files with 142 additions and 65 deletions
|
@ -509,19 +509,24 @@ class PusherBackgroundUpdatesStore(SQLBaseStore):
|
|||
async def _set_device_id_for_pushers(
|
||||
self, progress: JsonDict, batch_size: int
|
||||
) -> int:
|
||||
"""Background update to populate the device_id column of the pushers table."""
|
||||
"""
|
||||
Background update to populate the device_id column and clear the access_token
|
||||
column for the pushers table.
|
||||
"""
|
||||
last_pusher_id = progress.get("pusher_id", 0)
|
||||
|
||||
def set_device_id_for_pushers_txn(txn: LoggingTransaction) -> int:
|
||||
txn.execute(
|
||||
"""
|
||||
SELECT p.id, at.device_id
|
||||
SELECT
|
||||
p.id AS pusher_id,
|
||||
p.device_id AS pusher_device_id,
|
||||
at.device_id AS token_device_id
|
||||
FROM pushers AS p
|
||||
INNER JOIN access_tokens AS at
|
||||
LEFT JOIN access_tokens AS at
|
||||
ON p.access_token = at.id
|
||||
WHERE
|
||||
p.access_token IS NOT NULL
|
||||
AND at.device_id IS NOT NULL
|
||||
AND p.id > ?
|
||||
ORDER BY p.id
|
||||
LIMIT ?
|
||||
|
@ -533,13 +538,27 @@ class PusherBackgroundUpdatesStore(SQLBaseStore):
|
|||
if len(rows) == 0:
|
||||
return 0
|
||||
|
||||
# The reason we're clearing the access_token column here is a bit subtle.
|
||||
# When a user logs out, we:
|
||||
# (1) delete the access token
|
||||
# (2) delete the device
|
||||
#
|
||||
# Ideally, we would delete the pushers only via its link to the device
|
||||
# during (2), but since this background update might not have fully run yet,
|
||||
# we're still deleting the pushers via the access token during (1).
|
||||
self.db_pool.simple_update_many_txn(
|
||||
txn=txn,
|
||||
table="pushers",
|
||||
key_names=("id",),
|
||||
key_values=[(row["id"],) for row in rows],
|
||||
value_names=("device_id",),
|
||||
value_values=[(row["device_id"],) for row in rows],
|
||||
key_values=[(row["pusher_id"],) for row in rows],
|
||||
value_names=("device_id", "access_token"),
|
||||
# If there was already a device_id on the pusher, we only want to clear
|
||||
# the access_token column, so we keep the existing device_id. Otherwise,
|
||||
# we set the device_id we got from joining the access_tokens table.
|
||||
value_values=[
|
||||
(row["pusher_device_id"] or row["token_device_id"], None)
|
||||
for row in rows
|
||||
],
|
||||
)
|
||||
|
||||
self.db_pool.updates._background_update_progress_txn(
|
||||
|
@ -568,7 +587,6 @@ class PusherStore(PusherWorkerStore, PusherBackgroundUpdatesStore):
|
|||
async def add_pusher(
|
||||
self,
|
||||
user_id: str,
|
||||
access_token: Optional[int],
|
||||
kind: str,
|
||||
app_id: str,
|
||||
app_display_name: str,
|
||||
|
@ -581,13 +599,13 @@ class PusherStore(PusherWorkerStore, PusherBackgroundUpdatesStore):
|
|||
profile_tag: str = "",
|
||||
enabled: bool = True,
|
||||
device_id: Optional[str] = None,
|
||||
access_token_id: Optional[int] = None,
|
||||
) -> None:
|
||||
async with self._pushers_id_gen.get_next() as stream_id:
|
||||
await self.db_pool.simple_upsert(
|
||||
table="pushers",
|
||||
keyvalues={"app_id": app_id, "pushkey": pushkey, "user_name": user_id},
|
||||
values={
|
||||
"access_token": access_token,
|
||||
"kind": kind,
|
||||
"app_display_name": app_display_name,
|
||||
"device_display_name": device_display_name,
|
||||
|
@ -599,6 +617,10 @@ class PusherStore(PusherWorkerStore, PusherBackgroundUpdatesStore):
|
|||
"id": stream_id,
|
||||
"enabled": enabled,
|
||||
"device_id": device_id,
|
||||
# XXX(quenting): We're only really persisting the access token ID
|
||||
# when updating an existing pusher. This is in case the
|
||||
# 'set_device_id_for_pushers' background update hasn't finished yet.
|
||||
"access_token": access_token_id,
|
||||
},
|
||||
desc="add_pusher",
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue