Correctly handle account with invalid access token

Show a popup saying the session was signed out and cleanup
the models data, instead of spamming the users with
never-ending errors.
This commit is contained in:
miruka
2020-09-04 11:21:36 -04:00
parent 3c9895b0b2
commit 7b6478f514
9 changed files with 92 additions and 9 deletions

View File

@@ -18,7 +18,7 @@ from appdirs import AppDirs
import nio
from . import __app_name__
from .errors import MatrixError
from .errors import MatrixError, MatrixInvalidAccessToken
from .matrix_client import MatrixClient
from .media_cache import MediaCache
from .models import SyncId
@@ -305,6 +305,11 @@ class Backend:
client = self.clients.pop(user_id, None)
if client:
try:
await client.logout()
except MatrixInvalidAccessToken:
pass
self.models["accounts"].pop(user_id, None)
self.models["matching_accounts"].pop(user_id, None)
self.models[user_id, "uploads"].clear()
@@ -317,8 +322,6 @@ class Backend:
self.models[user_id, "rooms"].clear()
await client.logout()
await self.saved_accounts.delete(user_id)

View File

@@ -33,6 +33,12 @@ class MatrixError(Exception):
return cls(response.transport_response.status, response.status_code)
@dataclass
class MatrixInvalidAccessToken(MatrixError):
http_code: int = 401
m_code: str = "M_UNKNOWN_TOKEN"
@dataclass
class MatrixUnauthorized(MatrixError):
http_code: int = 401

View File

@@ -36,8 +36,9 @@ from nio.crypto import async_generator_from_data
from . import __app_name__, __display_name__, utils
from .errors import (
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
MatrixError, MatrixForbidden, MatrixNotFound, MatrixTooLarge,
MatrixUnauthorized, UneededThumbnail, UserFromOtherServerDisallowed,
MatrixError, MatrixForbidden, MatrixInvalidAccessToken, MatrixNotFound,
MatrixTooLarge, MatrixUnauthorized, UneededThumbnail,
UserFromOtherServerDisallowed,
)
from .html_markdown import HTML_PROCESSOR as HTML
from .media_cache import Media, Thumbnail
@@ -47,7 +48,9 @@ from .models.items import (
from .models.model_store import ModelStore
from .nio_callbacks import NioCallbacks
from .presence import Presence
from .pyotherside_events import AlertRequested, LoopException
from .pyotherside_events import (
AlertRequested, InvalidAccessToken, LoopException,
)
if TYPE_CHECKING:
from .backend import Backend
@@ -201,6 +204,8 @@ class MatrixClient(nio.AsyncClient):
# {room_id: event}
self.power_level_events: Dict[str, nio.PowerLevelsEvent] = {}
self.invalid_disconnecting: bool = False
self.nio_callbacks = NioCallbacks(self)
@@ -236,7 +241,15 @@ class MatrixClient(nio.AsyncClient):
response = await super()._send(*args, **kwargs)
if isinstance(response, nio.ErrorResponse):
raise MatrixError.from_nio(response)
try:
raise MatrixError.from_nio(response)
except MatrixInvalidAccessToken:
if not self.invalid_disconnecting:
self.invalid_disconnecting = True
InvalidAccessToken(self.user_id)
await self.backend.logout_client(self.user_id)
raise
return response

View File

@@ -98,3 +98,10 @@ class DevicesUpdated(PyOtherSideEvent):
"""Indicate changes in devices for us or users we share a room with."""
our_user_id: str = field()
@dataclass
class InvalidAccessToken(PyOtherSideEvent):
"""Indicate one of our account's access token is invalid or revoked."""
user_id: str = field()