From 47df060beef382e02c6146a792f507b66636ca56 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 11 Mar 2021 14:21:51 +0100 Subject: [PATCH] Added fundaments of SecretStorage vault This class will handle the storing and processing of secrets. Such as tokens. It will try to use the system keyring by default. Falling back to less secure methods, if the user doesn't allow access to the keyring or if the back-end is unsupported. CURA-7180 keyring storage --- cura/OAuth2/AuthorizationService.py | 11 +++++++---- cura/OAuth2/SecretStorage.py | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 cura/OAuth2/SecretStorage.py diff --git a/cura/OAuth2/AuthorizationService.py b/cura/OAuth2/AuthorizationService.py index df1c47f279..d0077cb9a6 100644 --- a/cura/OAuth2/AuthorizationService.py +++ b/cura/OAuth2/AuthorizationService.py @@ -17,7 +17,8 @@ from UM.i18n import i18nCatalog from cura.OAuth2.AuthorizationHelpers import AuthorizationHelpers, TOKEN_TIMESTAMP_FORMAT from cura.OAuth2.LocalAuthorizationServer import LocalAuthorizationServer from cura.OAuth2.Models import AuthenticationResponse -import keyring +from cura.OAuth2.SecretStorage import SecretStorage + i18n_catalog = i18nCatalog("cura") if TYPE_CHECKING: @@ -52,6 +53,8 @@ class AuthorizationService: self.onAuthStateChanged.connect(self._authChanged) + self._secret_storage = SecretStorage() + 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() @@ -232,7 +235,7 @@ class AuthorizationService: # Since we stored all the sensitive stuff in the keyring, restore that now. # Don't store the access_token, as it's very long and that (or tried workarounds) causes issues on Windows. - preferences_data["refresh_token"] = keyring.get_password("cura", "refresh_token") + preferences_data["refresh_token"] = self._secret_storage["refresh_token"] if preferences_data: self._auth_data = AuthenticationResponse(**preferences_data) @@ -263,7 +266,8 @@ class AuthorizationService: # Store all the sensitive stuff in the keyring # Don't store the access_token, as it's very long and that (or tried workarounds) causes issues on Windows. - keyring.set_password("cura", "refresh_token", auth_data.refresh_token) + self._secret_storage["refresh_token"] = auth_data.refresh_token + # And remove that data again so it isn't stored in the preferences. # Keep the access_token, as it's very long and that (or tried workarounds) causes issues on Windows. @@ -275,4 +279,3 @@ class AuthorizationService: self._preferences.resetPreference(self._settings.AUTH_DATA_PREFERENCE_KEY) self.accessTokenChanged.emit() - diff --git a/cura/OAuth2/SecretStorage.py b/cura/OAuth2/SecretStorage.py new file mode 100644 index 0000000000..42f6164be2 --- /dev/null +++ b/cura/OAuth2/SecretStorage.py @@ -0,0 +1,20 @@ +import keyring + + +class SecretStorage: + def __init__(self): + self._stored_secrets = [] + + def __delitem__(self, key): + if key in self._stored_secrets: + del self._stored_secrets[key] + keyring.delete_password("cura", key) + + def __setitem__(self, key, value): + self._stored_secrets.append(key) + keyring.set_password("cura", key, value) + + def __getitem__(self, key): + if key in self._stored_secrets: + return keyring.get_password("cura", key) + return None