From dadda742ecca248151bc0d2bdda2561e338c1370 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 29 Mar 2021 16:31:31 +0200 Subject: [PATCH 1/3] Add pywin32 to the requirements Allows the keyring library to use the Windows Credential Manager as a backend. CURA-7180 --- requirements.txt | 2 ++ resources/qml/Dialogs/AboutDialog.qml | 1 + 2 files changed, 3 insertions(+) diff --git a/requirements.txt b/requirements.txt index b13e160868..2233fb81e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -32,3 +32,5 @@ urllib3==1.25.6 PyYAML==5.1.2 zeroconf==0.24.1 comtypes==1.1.7 +pywin32==300 +keyring==23.0.1 diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index a0d8b6c4e6..1ee0b31040 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -159,6 +159,7 @@ UM.Dialog projectsModel.append({ name: "libnest2d", description: catalog.i18nc("@label", "Polygon packing library, developed by Prusa Research"), license: "LGPL", url: "https://github.com/tamasmeszaros/libnest2d" }); projectsModel.append({ name: "pynest2d", description: catalog.i18nc("@label", "Python bindings for libnest2d"), license: "LGPL", url: "https://github.com/Ultimaker/pynest2d" }); projectsModel.append({ name: "keyring", description: catalog.i18nc("@label", "Support library for system keyring access"), license: "MIT", url: "https://github.com/jaraco/keyring" }); + projectsModel.append({ name: "pywin32", description: catalog.i18nc("@label", "Python extensions for Microsoft Windows"), license: "PSF", url: "https://github.com/mhammond/pywin32" }); projectsModel.append({ name: "Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); projectsModel.append({ name: "Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); projectsModel.append({ name: "AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); From dbb15b7c7190e28a6946d98499f494cdc1f1f8bd Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 29 Mar 2021 16:33:59 +0200 Subject: [PATCH 2/3] Account for exception occured when storing long tokens on Windows The Windows Credential Manager allows for up to 256bits passwords. If a password longer than that is attempted to be written, it will throw a BaseException. CURA-7180 --- cura/OAuth2/KeyringAttribute.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/cura/OAuth2/KeyringAttribute.py b/cura/OAuth2/KeyringAttribute.py index c64ea86975..6281f9ae92 100644 --- a/cura/OAuth2/KeyringAttribute.py +++ b/cura/OAuth2/KeyringAttribute.py @@ -1,11 +1,16 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional, Type +from typing import Type, TYPE_CHECKING import keyring +from keyring.backend import KeyringBackend +from keyring.errors import NoKeyringError, PasswordSetError from UM.Logger import Logger +if TYPE_CHECKING: + from cura.OAuth2.Models import BaseModel + class KeyringAttribute: """ @@ -15,7 +20,7 @@ class KeyringAttribute: if self._store_secure: try: return keyring.get_password("cura", self._keyring_name) - except keyring.errors.NoKeyringError: + except NoKeyringError: self._store_secure = False Logger.logException("w", "No keyring backend present") return getattr(instance, self._name) @@ -27,14 +32,20 @@ class KeyringAttribute: setattr(instance, self._name, None) try: keyring.set_password("cura", self._keyring_name, value) - except keyring.errors.PasswordSetError: + except PasswordSetError: self._store_secure = False setattr(instance, self._name, value) Logger.logException("w", "Keyring access denied") - except keyring.errors.NoKeyringError: + except NoKeyringError: self._store_secure = False setattr(instance, self._name, value) Logger.logException("w", "No keyring backend present") + except BaseException as e: + # A BaseException can occur in Windows when the keyring attempts to write a token longer than 256 + # characters in the Windows Credentials Manager. + self._store_secure = False + setattr(instance, self._name, value) + Logger.log("w", "Keyring failed: {}".format(e)) else: setattr(instance, self._name, value) @@ -43,7 +54,7 @@ class KeyringAttribute: self._keyring_name = name self._store_secure = False try: - self._store_secure = keyring.backend.KeyringBackend.viable - except keyring.errors.NoKeyringError: + self._store_secure = KeyringBackend.viable + except NoKeyringError: Logger.logException("w", "Could not use keyring") setattr(owner, self._name, None) From fb5d59db32bbbfb48acc96a33602790cde955987 Mon Sep 17 00:00:00 2001 From: Kostas Karmas Date: Mon, 29 Mar 2021 17:03:09 +0200 Subject: [PATCH 3/3] Fix comment The Windows Credential Manager actually fails if the password is more than 1024 bits long. CURA-7180 --- cura/OAuth2/KeyringAttribute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/OAuth2/KeyringAttribute.py b/cura/OAuth2/KeyringAttribute.py index 6281f9ae92..64e813d242 100644 --- a/cura/OAuth2/KeyringAttribute.py +++ b/cura/OAuth2/KeyringAttribute.py @@ -41,7 +41,7 @@ class KeyringAttribute: setattr(instance, self._name, value) Logger.logException("w", "No keyring backend present") except BaseException as e: - # A BaseException can occur in Windows when the keyring attempts to write a token longer than 256 + # A BaseException can occur in Windows when the keyring attempts to write a token longer than 1024 # characters in the Windows Credentials Manager. self._store_secure = False setattr(instance, self._name, value)