Fix setting empty auth tokens in the keyring on startup

When Cura is starting up, it reads the authentication data from the preferences (cura.cfg). If
the auth tokens have previously been stored in the keyring, it means that their values will be null
in the cura.cfg file. Therefore, on startup, Cura reads the tokens as none from the preferences and
then sets the empty values in the keyring as tokens. This leads to the user being signed off every
time Cura restarts on Mac.

On Windows, the access token was still stored in the preferences, so on startup it was safe. The
refresh token, on the other hand, had the same issue as on Mac, which means that on startup it was
read as None from the cura.cfg and was stored in the keyring as an empty string. This meant that,
even though on startup (on windows) the user was kept signed in, the next time Cura was attempting
to refresh the access token (after 7-8 minutes), it wouldn't be able, since its refresh token was
read as "" from the keyring. Also, if the user would close Cura and reopen it after 10 minutes
(so after the access token had expired) then they would be signed off on windows too.

This commit fixes that by making sure that if the given value of the refresh and access tokens are
empty, then they will not be stored in the keyring.

CURA-8178
This commit is contained in:
Kostas Karmas 2021-04-15 17:46:36 +02:00
parent d84743990d
commit 07594f17a7

View File

@ -45,25 +45,26 @@ class KeyringAttribute:
def __set__(self, instance: "BaseModel", value: Optional[str]): def __set__(self, instance: "BaseModel", value: Optional[str]):
if self._store_secure: if self._store_secure:
setattr(instance, self._name, None) setattr(instance, self._name, None)
try: if value is not None:
keyring.set_password("cura", self._keyring_name, value if value is not None else "") try:
except PasswordSetError: keyring.set_password("cura", self._keyring_name, value)
self._store_secure = False except PasswordSetError:
if self._name not in DONT_EVER_STORE_LOCALLY: self._store_secure = False
setattr(instance, self._name, value) if self._name not in DONT_EVER_STORE_LOCALLY:
Logger.logException("w", "Keyring access denied") setattr(instance, self._name, value)
except NoKeyringError: Logger.logException("w", "Keyring access denied")
self._store_secure = False except NoKeyringError:
if self._name not in DONT_EVER_STORE_LOCALLY: self._store_secure = False
setattr(instance, self._name, value) if self._name not in DONT_EVER_STORE_LOCALLY:
Logger.logException("w", "No keyring backend present") setattr(instance, self._name, value)
except BaseException as e: Logger.logException("w", "No keyring backend present")
# A BaseException can occur in Windows when the keyring attempts to write a token longer than 1024 except BaseException as e:
# characters in the Windows Credentials Manager. # A BaseException can occur in Windows when the keyring attempts to write a token longer than 1024
self._store_secure = False # characters in the Windows Credentials Manager.
if self._name not in DONT_EVER_STORE_LOCALLY: self._store_secure = False
setattr(instance, self._name, value) if self._name not in DONT_EVER_STORE_LOCALLY:
Logger.log("w", "Keyring failed: {}".format(e)) setattr(instance, self._name, value)
Logger.log("w", "Keyring failed: {}".format(e))
else: else:
setattr(instance, self._name, value) setattr(instance, self._name, value)