diff --git a/cura/OAuth2/AuthorizationHelpers.py b/cura/OAuth2/AuthorizationHelpers.py index a654ee4bdb..1bc0d545f4 100644 --- a/cura/OAuth2/AuthorizationHelpers.py +++ b/cura/OAuth2/AuthorizationHelpers.py @@ -16,6 +16,7 @@ from UM.TaskManagement.HttpRequestManager import HttpRequestManager # To downlo catalog = i18nCatalog("cura") TOKEN_TIMESTAMP_FORMAT = "%Y-%m-%d %H:%M:%S" +REQUEST_TIMEOUT = 5 # Seconds class AuthorizationHelpers: @@ -52,7 +53,8 @@ class AuthorizationHelpers: data = urllib.parse.urlencode(data).encode("UTF-8"), headers_dict = headers, callback = lambda response: self.parseTokenResponse(response, callback), - error_callback = lambda response, _: self.parseTokenResponse(response, callback) + error_callback = lambda response, _: self.parseTokenResponse(response, callback), + timeout = REQUEST_TIMEOUT ) def getAccessTokenUsingRefreshToken(self, refresh_token: str, callback: Callable[[AuthenticationResponse], None]) -> None: @@ -75,7 +77,9 @@ class AuthorizationHelpers: data = urllib.parse.urlencode(data).encode("UTF-8"), headers_dict = headers, callback = lambda response: self.parseTokenResponse(response, callback), - error_callback = lambda response, _: self.parseTokenResponse(response, callback) + error_callback = lambda response, _: self.parseTokenResponse(response, callback), + urgent = True, + timeout = REQUEST_TIMEOUT ) def parseTokenResponse(self, token_response: QNetworkReply, callback: Callable[[AuthenticationResponse], None]) -> None: @@ -120,7 +124,8 @@ class AuthorizationHelpers: check_token_url, headers_dict = headers, callback = lambda reply: self._parseUserProfile(reply, success_callback, failed_callback), - error_callback = lambda _, _2: failed_callback() if failed_callback is not None else None + error_callback = lambda _, _2: failed_callback() if failed_callback is not None else None, + timeout = REQUEST_TIMEOUT ) def _parseUserProfile(self, reply: QNetworkReply, success_callback: Optional[Callable[[UserProfile], None]], failed_callback: Optional[Callable[[], None]] = None) -> None: diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index 62bf31982a..7a1bfb75f7 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -6,13 +6,14 @@ from datetime import datetime, timedelta from typing import Callable, Dict, Optional, TYPE_CHECKING, Union from urllib.parse import urlencode, quote_plus -from PyQt6.QtCore import QUrl +from PyQt6.QtCore import QUrl, QTimer from PyQt6.QtGui import QDesktopServices from UM.Logger import Logger from UM.Message import Message from UM.Signal import Signal from UM.i18n import i18nCatalog +from UM.TaskManagement.HttpRequestManager import HttpRequestManager # To download log-in tokens. from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers, TOKEN_TIMESTAMP_FORMAT from cura.OAuth2.LocalAuthorizationServer import LocalAuthorizationServer from cura.OAuth2.Models import AuthenticationResponse, BaseModel @@ -53,6 +54,12 @@ class AuthorizationService: self.onAuthStateChanged.connect(self._authChanged) + self._refresh_token_retries = 0 + self._refresh_token_retry_timer = QTimer() + self._refresh_token_retry_timer.setInterval(1000) + self._refresh_token_retry_timer.setSingleShot(True) + self._refresh_token_retry_timer.timeout.connect(self.refreshAccessToken) + def _authChanged(self, logged_in): if logged_in and self._unable_to_get_data_message is not None: self._unable_to_get_data_message.hide() @@ -163,16 +170,29 @@ class AuthorizationService: return def process_auth_data(response: AuthenticationResponse) -> None: + self._currently_refreshing_token = False + if response.success: + self._refresh_token_retries = 0 self._storeAuthData(response) + HttpRequestManager.getInstance().setDelayRequests(False) self.onAuthStateChanged.emit(logged_in = True) else: - Logger.warning("Failed to get a new access token from the server.") - self.onAuthStateChanged.emit(logged_in = False) + if self._refresh_token_retries >= 15: + self._refresh_token_retries = 0 + Logger.warning("Failed to get a new access token from the server, giving up.") + HttpRequestManager.getInstance().setDelayRequests(False) + self.onAuthStateChanged.emit(logged_in = False) + else: + # Retry a bit later, network may be offline right now and will hopefully be back soon + Logger.warning("Failed to get a new access token from the server, retrying later.") + self._refresh_token_retries += 1 + self._refresh_token_retry_timer.start() if self._currently_refreshing_token: Logger.debug("Was already busy refreshing token. Do not start a new request.") return + HttpRequestManager.getInstance().setDelayRequests(True) self._currently_refreshing_token = True self._auth_helpers.getAccessTokenUsingRefreshToken(self._auth_data.refresh_token, process_auth_data)