From 3f92b46ac8fad124aeff09abec65a8a3402bd7a3 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 22 Nov 2021 18:52:43 +0100 Subject: [PATCH] Don't restart refresh token while it's already processing If two requests to the API occur at the same time, they will both see at the same time that they need an access token, and if it is expired they will both see that it needs refreshing. The server then sees two refreshes, both with the same refresh token. This is not allowed. The second one then gets a failure to refresh the token, which causes the user to log out. Instead, we'll stop one of the refresh requests. They were fire-and-forget anyway, so it's not needed to actually continue the request. Contributes to issue CURA-8539. --- cura/OAuth2/AuthorizationService.py | 6 ++++++ plugins/Toolbox/src/CloudSync/CloudPackageChecker.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 98c09c6873..0884ec8901 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -46,6 +46,7 @@ class AuthorizationService: self._user_profile = None # type: Optional["UserProfile"] self._preferences = preferences self._server = LocalAuthorizationServer(self._auth_helpers, self._onAuthStateChanged, daemon=True) + self._currently_refreshing_token = False # Whether we are currently in the process of refreshing auth. Don't make new requests while busy. self._unable_to_get_data_message = None # type: Optional[Message] @@ -168,6 +169,10 @@ class AuthorizationService: Logger.warning("Failed to get a new access token from the server.") self.onAuthStateChanged.emit(logged_in = False) + if self._currently_refreshing_token: + Logger.debug("Was already busy refreshing token. Do not start a new request.") + return + self._currently_refreshing_token = True self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token, process_auth_data) def deleteAuthData(self) -> None: @@ -285,6 +290,7 @@ class AuthorizationService: return self._auth_data = auth_data + self._currently_refreshing_token = False if auth_data: self.getUserProfile() self._preferences.setValue(self._settings.AUTH_DATA_PREFERENCE_KEY, json.dumps(auth_data.dump())) diff --git a/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py b/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py index 4c1818e4ee..6d2ed1dcbd 100644 --- a/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py +++ b/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py @@ -66,7 +66,7 @@ class CloudPackageChecker(QObject): self._application.getHttpRequestManager().get(url, callback = self._onUserPackagesRequestFinished, error_callback = self._onUserPackagesRequestFinished, - timeout=10, + timeout = 10, scope = self._scope) def _onUserPackagesRequestFinished(self, reply: "QNetworkReply", error: Optional["QNetworkReply.NetworkError"] = None) -> None: