Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit bc8a5c0

Browse files
committed
Notify auth providers on logout
Provide a hook by which auth providers can be notified of logouts.
1 parent 846a94f commit bc8a5c0

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

docs/password_auth_providers.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,13 @@ Password auth provider classes may optionally provide the following methods.
8282

8383
The method should return a Twisted ``Deferred`` object, which resolves to
8484
``True`` if authentication is successful, and ``False`` if not.
85+
86+
``someprovider.on_logged_out``\(*user_id*, *device_id*, *access_token*)
87+
88+
This method, if implemented, is called when a user logs out. It is passed
89+
the qualified user ID, the ID of the deactivated device (if any: access
90+
tokens are occasionally created without an associated device ID), and the
91+
(now deactivated) access token.
92+
93+
It may return a Twisted ``Deferred`` object; the logout request will wait
94+
for the deferred to complete but the result is ignored.

synapse/handlers/auth.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ def deactivate_account(self, user_id):
682682
yield self.store.user_delete_threepids(user_id)
683683
yield self.store.user_set_password_hash(user_id, None)
684684

685+
@defer.inlineCallbacks
685686
def delete_access_token(self, access_token):
686687
"""Invalidate a single access token
687688
@@ -691,8 +692,19 @@ def delete_access_token(self, access_token):
691692
Returns:
692693
Deferred
693694
"""
694-
return self.store.delete_access_token(access_token)
695+
user_info = yield self.auth.get_user_by_access_token(access_token)
696+
yield self.store.delete_access_token(access_token)
697+
698+
# see if any of our auth providers want to know about this
699+
for provider in self.password_providers:
700+
if hasattr(provider, "on_logged_out"):
701+
yield provider.on_logged_out(
702+
user_id=str(user_info["user"]),
703+
device_id=user_info["device_id"],
704+
access_token=access_token,
705+
)
695706

707+
@defer.inlineCallbacks
696708
def delete_access_tokens_for_user(self, user_id, except_token_id=None,
697709
device_id=None):
698710
"""Invalidate access tokens belonging to a user
@@ -707,10 +719,20 @@ def delete_access_tokens_for_user(self, user_id, except_token_id=None,
707719
Returns:
708720
Deferred
709721
"""
710-
return self.store.user_delete_access_tokens(
722+
tokens_and_devices = yield self.store.user_delete_access_tokens(
711723
user_id, except_token_id=except_token_id, device_id=device_id,
712724
)
713725

726+
# see if any of our auth providers want to know about this
727+
for provider in self.password_providers:
728+
if hasattr(provider, "on_logged_out"):
729+
for token, device_id in tokens_and_devices:
730+
yield provider.on_logged_out(
731+
user_id=user_id,
732+
device_id=device_id,
733+
access_token=token,
734+
)
735+
714736
@defer.inlineCallbacks
715737
def add_threepid(self, user_id, medium, address, validated_at):
716738
# 'Canonicalise' email addresses down to lower case.

synapse/storage/registration.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ def user_delete_access_tokens(self, user_id, except_token_id=None,
255255
If None, tokens associated with any device (or no device) will
256256
be deleted
257257
Returns:
258-
defer.Deferred:
258+
defer.Deferred[list[str, str|None]]: a list of the deleted tokens
259+
and device IDs
259260
"""
260261
def f(txn):
261262
keyvalues = {
@@ -272,21 +273,23 @@ def f(txn):
272273
values.append(except_token_id)
273274

274275
txn.execute(
275-
"SELECT token FROM access_tokens WHERE %s" % where_clause,
276+
"SELECT token, device_id FROM access_tokens WHERE %s" % where_clause,
276277
values
277278
)
278-
rows = self.cursor_to_dict(txn)
279+
tokens_and_devices = [(r[0], r[1]) for r in txn]
279280

280-
for row in rows:
281+
for token, _ in tokens_and_devices:
281282
self._invalidate_cache_and_stream(
282-
txn, self.get_user_by_access_token, (row["token"],)
283+
txn, self.get_user_by_access_token, (token,)
283284
)
284285

285286
txn.execute(
286287
"DELETE FROM access_tokens WHERE %s" % where_clause,
287288
values
288289
)
289290

291+
return tokens_and_devices
292+
290293
yield self.runInteraction(
291294
"user_delete_access_tokens", f,
292295
)

0 commit comments

Comments
 (0)