2525from synapse .push import Pusher , PusherConfig , PusherConfigException
2626from synapse .push .pusher import PusherFactory
2727from synapse .replication .http .push import ReplicationRemovePusherRestServlet
28- from synapse .types import JsonDict , RoomStreamToken
28+ from synapse .types import JsonDict , RoomStreamToken , StrCollection
2929from synapse .util .async_helpers import concurrently_execute
3030from synapse .util .threepids import canonicalise_email
3131
@@ -97,7 +97,6 @@ def start(self) -> None:
9797 async def add_or_update_pusher (
9898 self ,
9999 user_id : str ,
100- access_token : Optional [int ],
101100 kind : str ,
102101 app_id : str ,
103102 app_display_name : str ,
@@ -128,6 +127,22 @@ async def add_or_update_pusher(
128127 # stream ordering, so it will process pushes from this point onwards.
129128 last_stream_ordering = self .store .get_room_max_stream_ordering ()
130129
130+ # Before we actually persist the pusher, we check if the user already has one
131+ # for this app ID and pushkey. If so, we want to keep the access token and
132+ # device ID in place, since this could be one device modifying
133+ # (e.g. enabling/disabling) another device's pusher.
134+ # XXX(quenting): Even though we're not persisting the access_token_id for new
135+ # pushers anymore, we still need to copy existing access_token_ids over when
136+ # updating a pusher, in case the "set_device_id_for_pushers" background update
137+ # hasn't run yet.
138+ access_token_id = None
139+ existing_config = await self ._get_pusher_config_for_user_by_app_id_and_pushkey (
140+ user_id , app_id , pushkey
141+ )
142+ if existing_config :
143+ device_id = existing_config .device_id
144+ access_token_id = existing_config .access_token
145+
131146 # we try to create the pusher just to validate the config: it
132147 # will then get pulled out of the database,
133148 # recreated, added and started: this means we have only one
@@ -136,7 +151,6 @@ async def add_or_update_pusher(
136151 PusherConfig (
137152 id = None ,
138153 user_name = user_id ,
139- access_token = access_token ,
140154 profile_tag = profile_tag ,
141155 kind = kind ,
142156 app_id = app_id ,
@@ -151,23 +165,12 @@ async def add_or_update_pusher(
151165 failing_since = None ,
152166 enabled = enabled ,
153167 device_id = device_id ,
168+ access_token = access_token_id ,
154169 )
155170 )
156171
157- # Before we actually persist the pusher, we check if the user already has one
158- # this app ID and pushkey. If so, we want to keep the access token and device ID
159- # in place, since this could be one device modifying (e.g. enabling/disabling)
160- # another device's pusher.
161- existing_config = await self ._get_pusher_config_for_user_by_app_id_and_pushkey (
162- user_id , app_id , pushkey
163- )
164- if existing_config :
165- access_token = existing_config .access_token
166- device_id = existing_config .device_id
167-
168172 await self .store .add_pusher (
169173 user_id = user_id ,
170- access_token = access_token ,
171174 kind = kind ,
172175 app_id = app_id ,
173176 app_display_name = app_display_name ,
@@ -180,6 +183,7 @@ async def add_or_update_pusher(
180183 profile_tag = profile_tag ,
181184 enabled = enabled ,
182185 device_id = device_id ,
186+ access_token_id = access_token_id ,
183187 )
184188 pusher = await self .process_pusher_change_by_id (app_id , pushkey , user_id )
185189
@@ -199,7 +203,7 @@ async def remove_pushers_by_app_id_and_pushkey_not_user(
199203 )
200204 await self .remove_pusher (p .app_id , p .pushkey , p .user_name )
201205
202- async def remove_pushers_by_access_token (
206+ async def remove_pushers_by_access_tokens (
203207 self , user_id : str , access_tokens : Iterable [int ]
204208 ) -> None :
205209 """Remove the pushers for a given user corresponding to a set of
@@ -209,6 +213,8 @@ async def remove_pushers_by_access_token(
209213 user_id: user to remove pushers for
210214 access_tokens: access token *ids* to remove pushers for
211215 """
216+ # XXX(quenting): This is only needed until the "set_device_id_for_pushers"
217+ # background update finishes
212218 tokens = set (access_tokens )
213219 for p in await self .store .get_pushers_by_user_id (user_id ):
214220 if p .access_token in tokens :
@@ -220,6 +226,26 @@ async def remove_pushers_by_access_token(
220226 )
221227 await self .remove_pusher (p .app_id , p .pushkey , p .user_name )
222228
229+ async def remove_pushers_by_devices (
230+ self , user_id : str , devices : StrCollection
231+ ) -> None :
232+ """Remove the pushers for a given user corresponding to a set of devices
233+
234+ Args:
235+ user_id: user to remove pushers for
236+ devices: device IDs to remove pushers for
237+ """
238+ device_ids = set (devices )
239+ for p in await self .store .get_pushers_by_user_id (user_id ):
240+ if p .device_id in device_ids :
241+ logger .info (
242+ "Removing pusher for app id %s, pushkey %s, user %s" ,
243+ p .app_id ,
244+ p .pushkey ,
245+ p .user_name ,
246+ )
247+ await self .remove_pusher (p .app_id , p .pushkey , p .user_name )
248+
223249 def on_new_notifications (self , max_token : RoomStreamToken ) -> None :
224250 if not self .pushers :
225251 # nothing to do here.
0 commit comments